Сообщить об ошибке.

Подстановка значений Python в DB-API SQLite3

В операциях SQL обычно необходимо использовать значения переменных Python. Необходимо остерегаться использования строковых операций Python для сборки запросов, т.к. они уязвимы для атак с использованием SQL-инъекций. Например, злоумышленник может просто закрыть одинарную кавычку и ввести OR TRUE, чтобы выбрать все строки:

# Никогда не делай этого!
>>> symbol = input()
# ' OR TRUE; --
>>> sql = "SELECT * FROM stocks WHERE symbol = '%s'" % symbol
>>> print(sql)
# SELECT * FROM stocks WHERE symbol = '' OR TRUE; --'
>>> cur.execute(sql)

Во избежании атак с использованием SQL-инъекций, необходимо использовать подстановку параметров DB-API. Чтобы вставить переменную в строку запроса, используйте заполнитель в строке и подставьте фактические значения в запрос, передав их в виде кортежа значений во второй аргумент метода курсора Cursor.execute().

В операторе SQL может использоваться один из двух типов заполнителей: вопросительные знаки ? (стиль qmark) или именованные заполнители (именованный стиль). Для стиля qmark параметры должны представлять собой последовательность, длина которой должна соответствовать количеству заполнителей, иначе возникнет ошибка ProgrammingError. Для именованного стиля параметры должны быть экземпляром словаря dict (или подкласса), который должен содержать ключи для всех именованных параметров; любые дополнительные элементы игнорируются.

Пример обоих стилей:

con = sqlite3.connect(":memory:")
cur = con.execute("CREATE TABLE lang(name, first_appeared)")

# Это именованный стиль, используемый с `executemany()`:
data = (
    {"name": "C", "year": 1972},
    {"name": "Fortran", "year": 1957},
    {"name": "Python", "year": 1991},
    {"name": "Go", "year": 2009},
)
cur.executemany("INSERT INTO lang VALUES(:name, :year)", data)

# Это стиль `qmark`, используемый в `SELECT query`:
params = (1972,)
cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params)
print(cur.fetchall())