Проблема форматирования SQLite3 с параметрами - обновление существующего значения путем добавления другого значения - PullRequest
1 голос
/ 01 октября 2019

В настоящее время я изучаю, как использовать модуль sqlite3 в Python. Я пытаюсь написать код, который будет обновлять значение из столбца в sqlite, добавляя новое значение к существующему значению, но я сталкиваюсь с проблемами форматирования, которые я не знаю, как исправить ...

Я знаю, что основной синтаксис для этого (насколько мне известно) заключается в следующем:

sql_statement = "UPDATE table 
                 SET column_name = column_name + new_value 
                 WHERE condition;"

Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь вставитьимя столбца с использованием словарных параметров из python. Вот где проблема возникает в моем коде:

muscle = 'Lats'
num_sets = 5
week_num = 40

sql_statement = f"UPDATE WeeklyMuscleSets 
                 SET {muscle} = (:muscle) + (:num_sets) 
                 WHERE WeekID = (:week_num);"

parameters = {'muscle':muscle,'num_sets':num_sets,'week_num':week_num}

c.execute(sql_statement,parameters)

Код работает просто отлично, но вместо добавления к существующему значению в таблице он заменяет его. Я провел некоторое тестирование, и когда я вручную вводил значение для переменной «мышц», оно обновлялось очень хорошо.

muscle = 'Lats'
num_sets = 5
week_num = 40

sql_statement = f"UPDATE WeeklyMuscleSets 
                 SET {muscle} = Lats + (:num_sets) 
                 WHERE WeekID = (:week_num);"

parameters = {'num_sets':num_sets,'week_num':week_num}

c.execute(sql_statement,parameters)

Это также работало, когда я использовал форматирование f-строки для переменной мышц, однако язнать, что это плохая практика и делает код уязвимым для атак с использованием инъекций.

По какой-то причине, когда я использую параметры, он не добавляет новое значение к существующему, а заменяет его, и я не понимаю, почему. Любая помощь в этом с благодарностью!

Ответы [ 2 ]

0 голосов
/ 01 октября 2019

Вы уверены, что ваш код работает нормально? Согласно этой записи и этой нельзя использовать именованные заполнители для имен таблиц или столбцов. Вы пытаетесь использовать именованный заполнитель для столбца, поэтому я ожидаю, что будет возбуждено исключение.

На ум приходят два способа решения проблемы:

  1. Использовать строку{форматирование}. Как вы указали, у этого есть обратная сторона - разрешать атаки с использованием SQL-инъекций. Тем не менее, можно очистить данные от пользователя. Если безопасность так сильно беспокоит, вы, вероятно, должны использовать какой-то ORM вместо необработанного SQL.

  2. Перестройте свою таблицу так, чтобы она выглядела примерно так:

    create WeeklyMuscleSets (
        muscle varchar,
        number_of_sets number,
        week number
    )
    

    и ваш запрос будет выглядеть примерно так:

    update WeeklyMuscleSets 
    set number_of_sets = number_of_sets + :extra_sets
    where muscle = :muscle
    
0 голосов
/ 01 октября 2019

Это параметризованный запрос. Затем запрос и значения отправляются в двигатель СУБД отдельно, и СУБД использует значения в запросе parsed . Затем проанализированный запрос сохраняется и используется снова, поэтому производительность повышается, и внедрение SQL невозможно.

Если вы хотите добавить num_sets к текущему значению muscle, вы должны использовать muscle + :num_sets:

num_sets = 5
week_num = 40

sql_statement = f"UPDATE WeeklyMuscleSets 
                 SET muscle = muscle + :num_sets
                 WHERE WeekID = :week_num;"

parameters = {'num_sets':num_sets,'week_num':week_num}

c.execute(sql_statement,parameters)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...