Как использовать переменные в инструкции SQL в Python?
Хорошо, поэтому я не настолько опытен в Python.
У меня есть следующий код Python:
cursor.execute("INSERT INTO table VALUES var1, var2, var3,")
где var1
- целое число, var2
и var3
- строки.
Как я могу написать имена переменных без использования python, включая их как часть текста запроса?
Ответы
Ответ 1
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
Обратите внимание, что параметры передаются как кортеж.
API базы данных выполняет правильное экранирование и цитирование переменных. Будьте осторожны, чтобы не использовать оператор форматирования строк (%
), потому что
- он не выполняет никаких экранов или цитирования.
- он подвержен неконтролируемым атакам формата строки, например. SQL-инъекция.
Ответ 2
В разных реализациях Python DB-API разрешено использовать разные заполнители, поэтому вам нужно будет узнать, какой из них вы используете - это может быть (например, с MySQLdb):
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
или (например, с sqlite3 из стандартной библиотеки Python):
cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))
или другие (после VALUES
у вас может быть (:1, :2, :3)
или "named styles" (:fee, :fie, :fo)
или (%(fee)s, %(fie)s, %(fo)s)
, где вы передаете dict вместо карты в качестве второго аргумента execute
). Проверьте константу строки paramstyle
в используемом вами модуле API БД и найдите paramstyle в http://www.python.org/dev/peps/pep-0249/, чтобы увидеть, что весь параметр -pass-стили!
Ответ 3
Много способов. НЕ используйте самый очевидный (%s
с %
) в реальном коде, он открыт для атак.
Здесь copy-paste'd из pydoc sqlite3:
# Never do this -- insecure!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
# Do this instead
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print c.fetchone()
# Larger example that inserts many records at a time
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
('2006-04-06', 'SELL', 'IBM', 500, 53.00),
]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)
Дополнительные примеры, если вам нужно:
# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))
Ответ 4
http://www.amk.ca/python/writing/DB-API.html
Будьте осторожны, когда вы просто добавляете значения переменных в свои утверждения:
Представьте, что пользователь называет себя ';DROP TABLE Users;'
-
Вот почему вам нужно использовать sql escaping, который Python предоставляет вам, когда вы используете cursor.execute достойным образом. Пример в URL-адресе:
cursor.execute("insert into Attendees values (?, ?, ?)", (name,
seminar, paid) )