Используя SQLite3 с Python 2.5, я пытаюсь перебирать список и извлекать вес элемента из базы данных на основе имени элемента.
Я пробовал использовать "?" предлагается подстановка параметров для предотвращения SQL-инъекций, но она не работает. Например, когда я использую:
for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", item)
self.cursor.close()
Я получаю сообщение об ошибке:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 8 supplied.
Я считаю, что это каким-то образом вызвано первоначальным созданием базы данных; Созданный мной модуль, который фактически создает БД, имеет 8 привязок.
cursor.execute("""CREATE TABLE Equipment
(id INTEGER PRIMARY KEY,
name TEXT,
price INTEGER,
weight REAL,
info TEXT,
ammo_cap INTEGER,
availability_west TEXT,
availability_east TEXT)""")
Однако, когда я использую менее безопасную замену «% s» для каждого имени элемента, она работает нормально. Вот так:
for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = '%s'" % item)
self.cursor.close()
Я не могу понять, почему он думает, что у меня 8 привязок, когда я звоню только одному. Как я могу это исправить?
Да, я знаю. Я просто подумал, что код каким-то образом пытается использовать привязки, на которые ссылается оператор «create table». Я не понимал, что это относится к количеству букв в самом предмете.
Вы пробовали это? :
for item in self.inventory_names:
t = (item,)
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", t)
self.cursor.close()
cursor.execute () ожидает последовательность (список, кортеж) в качестве второго параметра. (-> ddaa)
Метод Cursor.execute()
ожидает последовательность в качестве второго параметра. Вы предоставляете строку длиной 8 символов.
Вместо этого используйте следующую форму:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", [item])
Ссылка на библиотеку Python: sqlite3 Объекты курсора.
Я потратил полдня, пытаясь понять, почему что-то вроде этого выдает мне ошибку:
cursor.execute("SELECT * from ? WHERE name = ?", (table_name, name))
только чтобы узнать, что таблица называет нельзя параметризовать. Надеюсь, это поможет другим сэкономить время.
Вы можете сделать что-то вроде: cursor.execute("SELECT * from %s WHERE name = ?" % table_name, (name,))
, хотя это может сделать вашу программу уязвимой для атак SQL-инъекций.
В ситуациях, когда пользовательский ввод определяет таблицу, я извлекаю имя таблицы из dict и вызываю исключение, если содержимое ввода является неожиданным. Вероятно, это не способ Лучший, но, похоже, менее подвержен SQL-инъекции.
@James Мне любопытно, в каких ситуациях вам нужно было изменить таблицу, в которую вы вставляете, на основе пользовательского ввода? Использование dict звучит как довольно хорошая идея для этой ситуации, я использую их всякий раз, когда я использовал бы оператор switch.
@ num1: в любое время, когда вы хотите иметь общий класс, который принимает имя таблицы в качестве параметра класса init (). Таким образом, вы не хотите жестко кодировать имя таблицы, но хотите, чтобы оно было переменной ...
Вы используете []
для имен таблиц и полей и ?
для значений,
Пришел сюда, ища, как передать несколько аргументов, иди запрос SQLite =)
Это ограничение SQL, SQLite или Python DB-API?
Цитирование (это то, что означают скобки?) с parens, похоже, работает для меня. Я продолжал пытаться (буквально) '?' но я продолжал получать
ProgrammingError: Incorrect number of bindings supplied. The current statement uses 0, and there are 1 supplied.
Когда я это сделал:
SELECT fact FROM factoids WHERE key LIKE (?)
вместо:
SELECT fact FROM factoids WHERE key LIKE '?'
Это сработало.
Это какая-то штука с питоном 2.6?
Если вы используете подстановку параметров sqlite3 (вместо строковой интерполяции Python% s), тогда? вообще не следует цитировать, то есть SELECT fact FROM factoids WHERE key LIKE ?
. Просто бывает, что добавление скобок в SQL не меняет смысла, поэтому SELECT fact FROM factoids WHERE key LIKE (?)
эквивалентен без ().
Если вы используете Django и ваш запрос - SELECT fact FROM factoids WHERE key LIKE "%s"
, вам также следует избегать кавычек. cursor.execute()
не распознает% s как привязку в этом запросе. Так что используйте cursor.execute("Select fact FROM factoids WHERE key LIKE %s", (key_name, ))
Пытаться
execute("select fact from factoids where key like ?", "%%s%" % val)
Вы вообще ничего не оборачиваете вокруг ?
, Python sqlite правильно преобразует его в цитируемый объект.
Аргумент cursor.execute
, представляющий значения, которые вам нужно вставить в базу данных, должен быть кортежем (последовательностью). Однако рассмотрите этот пример и посмотрите, что происходит:
>>> ('jason')
'jason'
>>> ('jason',)
('jason',)
В первом примере вместо этого вычисляется строка; поэтому правильный способ представления однозначного кортежа такой же, как во втором вычислении. Во всяком случае, приведенный ниже код исправляет вашу ошибку.
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item,))
Также указание аргументов значения cursor.execute
в виде строк (что вы и делаете) приводит к первой оценке в примере и приводит к полученной вами ошибке.
@Kirk, но подстановка параметров не работает для имен таблиц sqlite, поэтому приведенный выше правильный.
каждый элемент items должен быть кортежем. предполагая, что имена выглядят примерно так:
names = ['Joe', 'Bob', 'Mary']
вам следует сделать следующее:
for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item, ))
используя (item,), вы делаете его кортежем вместо строки.
Это вызовет множество запросов. N + 1 проблема.
У меня как-то есть полная очередь редактирования, поэтому я оставляю комментарий для редактирования. --- функция cursor.execute принимает 3 параметра: строку запроса, список повторяемых элементов, переключатель. здесь список элементов для одного элемента может быть составлен с помощью «[item]» или «(item,)» - принятый ответ - это просто еще одна форма решения, и это еще один @ proofit404
Модуль sqlite3
поддерживает виды заполнителей два для параметров:
Используйте один или несколько ?
, чтобы отметить позицию каждого параметра и предоставить список или кортеж параметров. Например.:
curs.execute("SELECT weight FROM Equipment WHERE name = ? AND price = ?",
['lead', 24])
Используйте заполнители :par
для каждого именованного параметра и укажите dict. Например.:
curs.execute("SELECT weight FROM Equipment WHERE name = :name AND price = :price",
{name: 'lead', price: 24})
Преимущества именованных параметров стиля в том, что вам не нужно беспокоиться о порядке параметров, и каждый :par
можно использовать несколько раз в больших / сложных SQL-запросах.
Как насчет разных параметров стиля? А какой sqlite3 поддерживает и где об этом написано? python.org/dev/peps/pep-0249/#paramstyle
Количество столбцов - это не количество привязок. Количество знаков «?» В запросе - это количество привязок.