формат переменных psycopg2 для создания запросов
Это не так важно, поэтому мне просто интересно следующее (Python 2.7):
Я только начал использовать psycopg и читать документы, в которых всегда используются строки (%s) и кортежи для передачи значений в запрос.Заполнителем переменных всегда должен быть %s
Итак, рассматривая следующий пример -
В таблице с именем 'test' с полями value_1 (varchar) и value_2 (int) создается запрос в виде:
value_1 = "test"
value_2 = "100"
cur.execute("INSERT INTO test (value_1,value_2) VALUES (%s,%s)",
(value_1,value_2))
Мой вопрос, если это плохая практика или даже проблематично использовать метод "формат" вместо этого (как показано ниже):
cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}',{value2})".
format(value1=value_1,value2=value_2))
Что вы скажете, основываясь на своем опыте, действительно ли это опасно или проблематично?3 ответа:
Вызов
cur.execute("INSERT INTO test (value_1,value_2) VALUES (%s,%s)",\ (value_1,value_2))
Имеет строковый параметр и дополнительный параметр, представляющий собой кортеж значений для подстановки. Это позволяет
psycopg2
интерполировать значения, и делать это более безопасно, чем простая строковая интерполяция.Документы по использованию для psycopg2 говорят
♯ передайте данные для заполнения заполнителей запроса и позвольте Psycopg выполнить
& sharp; правильное преобразование (больше никаких SQL-инъекций!)
> > > cur.выполнить ("вставить в тест (Нум данных) значения (%с, %S)", ... (100, "abc'Def"))
В вызове
cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}',{value2})".\ format(value1=value_1,value2=value_2))
Вы сами интерполируете значения и просто передаете полученную строку методу cursor execute.
Простая интерполяция восприимчива к SQL-инъекции. Вам, вероятно, лучше использовать первую форму.
Вы всегда должны рассматривать "маленькие таблицы Бобби".
Прочитав некоторые документы и исходный код и протестировав это самостоятельно, я понял это правильно. Простой ответ: это чертовски небезопасно. Не только для psycopg2, но и для любого модуля БД (по крайней мере, для тех, которые я тестировал). Связывая это с psycopg2, использование (%s), (переменная,) позволяет psycopg2 автоматически экранировать эти переменные, чтобы предотвратить такой беспорядок.
Мой тест для выяснения небольшого беспорядка, который он может создать:
cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}','{value2}')".\ format(value1=value_1,value2='1); drop table test; --killer instinct'))
Вот и все, тестовая таблица adiós: - P
Да, Psycopg2 использует %s для всех типов, psycopg2 преобразует параметры в их строковое представление и использует его в запросе
INSERT INTO test (value_1,value_2) VALUES('test','100');
Иногда может потребоваться привести некоторые значения к типу apropriate.
cur.execute("""INSERT INTO test (value_1,value_2) VALUES (%s,%s::integer)""", (value_1,value_2))
Предложенный вами метод является очень плохой практикой, у вас есть SQL-инъекция для нескольких возможных значений value_1 и value_2. например:
value_1="',0); rollback; drop table test ; --"