Я не могу заставить Python executemany для sqlite3 работать правильно

Я пытался использовать executemany для вставки значений в базу данных, но у меня это просто не сработало. Вот пример:

clist = []
clist.append("abc")
clist.append("def")
clist.append("ghi")
cursor.executemany("INSERT INTO myTable(data) values (?) ", clist)

Это дает мне следующую ошибку:

sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 3 supplied.

Однако, когда я меняю список, он отлично работает:

clist = ["a", "b"]
cursor.executemany("INSERT INTO myTable(data) values (?) ", clist)

Он работает так, как ожидалось! Я вижу данные в базе данных. Почему первый список не работает, а второй работает?

(PS: это всего лишь пример, а не фактический код. Для простоты я сделал небольшой тестовый пример).


person brainydexter    schedule 16.03.2011    source источник


Ответы (2)


Из того, что я знаю о executemany, вы имели в виду,

clist = [("abc", ), ("def", ), ("ghi", )]
cursor.executemany("INSERT INTO myTable(data) values(?)", clist)

Или что-то подобное. Не цитируйте меня по синтаксису для sqlite, я давно не использовал его в приложении, но вам нужна итерация кортежей (в более общем смысле итерации).

Похоже, ошибка, которую вы получаете, заключается в том, что она пытается перебрать каждую предоставленную вами строку, поэтому ваше утверждение работает так:

clist = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i')]

Я не знаю, что пытается выполнить ваш второй запрос, но, похоже, он обращается к другой таблице, поэтому я предполагаю, что нет информации о схеме, но если вы измените односимвольные строки на многосимвольные строки, он тоже потерпит неудачу .

person marr75    schedule 16.03.2011
comment
Оба они были одинаковыми столами. Мой плохой для опечатки. Исправлено в вопросе сейчас. Это простая таблица с одним полем в ней. - person brainydexter; 17.03.2011
comment
Не могли бы вы опубликовать этот комментарий здесь снова, о втором списке. Я думаю, что человек, опубликовавший свой ответ, удалил его, и с этим все пошло. - person brainydexter; 17.03.2011
comment
Я не знаю, что именно вы спрашиваете. Строки итерабельны в python, поэтому строка во многом похожа на кортеж символов. Вызов execute (и, соответственно, executemany) предполагает итерацию параметров, например (1, 2, 3, 'abc') или range(3) или любой объект, поддерживающий итерацию. Итак, поскольку строки поддерживают итерацию, они также работают как набор параметров. Ваш оператор execute ожидает итерацию с одним элементом, который выполняется вторым clist (список строк с одним символом), но не выполняется первым clist (список строк с 3 символами). - person marr75; 19.03.2011
comment
После выполнения команды conn.commit() необходимо обновить таблицу. - person Vinod; 26.02.2019

Просто для дополнения контекста: в тесно связанной ситуации я хотел вставить список поликортежей в таблицу, используя executemany как таковой:

res = [("John", "2j4o1h2n"), ("Paula", "lsohvoeemsy"), ("Ben", "l8ers")]

cur.executemany("INSERT INTO users (user, password) VALUES (?)", res)

Ожидая, что SQLite будет принимать по одному кортежу за раз (отсюда и единственная подстановка параметра ? в поле VALUES) и разбивать его на инкапсулированные атрибуты (в данном случае <username>, <password>), он потерпел неудачу с sqlite3.ProgrammingError исключение The current statement uses 1, and there are 2 supplied., так как SQLite ожидает отдельно подставленные атрибуты в поле VALUES (...). Итак, это исправляет это:

cur.executemany("INSERT INTO users (user, password) VALUES (?, ?)", res)

Это тривиальный случай, но может немного запутаться, надеюсь, это поможет тем, кто застрял.

person bossi    schedule 15.03.2013