Python и подготовленные SQL утверждения с использованием переменных - PullRequest
1 голос
/ 21 июня 2020

Я новичок в Python, но у меня есть проект, над которым я работаю, поэтому, пожалуйста, извините за любое рождество с моей стороны. Я пишу несколько операторов SQL в Python 2.7 (библиотеки еще не обновлены до 3), но я зацикливаюсь на передовой практике для них. Мы используем Sybase. Первоначально я использовал

query = "UPDATE DB..TABLE SET version = '{}' WHERE name = '{}'".format(app.version, app.name)
cursor.execute(query)

, но после дальнейшего чтения понял, что он открыт для инъекций. Затем я посмотрел на следующие шаги:

query = "UPDATE DB..TABLE SET version = '%s' WHERE name = '%s'" % (app.version, app.name)
cursor.execute(query)

Но заставил меня подумать, разве это не одно и то же?

Параметры также являются переменными, установленными argparse, что означает, что я должен используйте '' вокруг% s, иначе это приведет к ошибке недопустимого имени столбца. Что меня расстраивает, так как я также хочу иметь возможность передавать NULL (None в Python) по умолчанию, если какие-либо дополнительные флаги не установлены в других запросах, в противном случае он, очевидно, вставляет «NULL» как строку.

В этом конкретном примере 2 переменные устанавливаются из файла, который читает ConfigParser, но я думаю, что для переменных argparse это все равно. например,

[SECTION]
application=name
version=1.0

Я не совсем уверен, как лучше всего решить эту проблему, и да, я знаю «PYTHON 3 - ЛУЧШЕ ОБНОВЛЕНИЕ ДО ЭТОГО», как я сказал в начале, библиотеки находятся в процесс переноса.

Если вам нужна дополнительная информация, сообщите, и я дам вам все, что могу.

ОБНОВЛЕНИЕ *** Используя следующую строку стиля Param, которую я нашел в в некоторых документах sybase он может работать, но он не передает None для NULL и выдает ошибки, начиная думать, что это ограничение модуля sybase в python.

cursor.execute("SELECT * FROM DB..table where app_name=@app_name", {"@app_name": app_name})
or
params = {"@appname": app.name. "@appver": app.version}
sql = "INSERT INTO DB..table (app_name, app_version) VALUES (@appname, @appversion)
cursor.execute(sql, params)

Но есть проблема, если у вас есть глобальный список параметров, и вы отправляете его в запрос, который, если какие-либо из них None, снова дает вам много ошибок о том, что None, ДАЖЕ, если эти параметры c не используются в запросе. Думаю, я могу застрять здесь, выполняя инструкции IF для различных опций для нескольких вставок, чтобы обойти эту проблему None NULL.

Ответы [ 2 ]

1 голос
/ 25 июня 2020

Хорошо, теперь я решил эту проблему. Мне пришлось обновить модуль sybase, чтобы заставить его работать с None> NULL.

Как указано в обновленном вопросе. ниже показано, как я выполнял запросы.

cursor.execute("SELECT * FROM DB..table where app_name=@app_name", {"@app_name": app_name})
or
params = {"@appname": app.name. "@appver": app.version}
sql = "INSERT INTO DB..table (app_name, app_version) VALUES (@appname, @appversion)
cursor.execute(sql, params)
0 голосов
/ 21 июня 2020

Но заставило меня задуматься, разве это не одно и то же?

Да, это фактически одно и то же. Они оба широко открыты для инъекционной атаки.

Вместо этого сделайте это следующим образом:

query = "UPDATE DB..TABLE SET version = %s WHERE name = %s"
cursor.execute(query, [app.version, app.name])
...