Я пытаюсь использовать executemany
в Python для заполнения ряда строк.Python + sqlite3: executemany с «построенными» значениями
Однако, я получаю:
sqlite3.OperationalError: 3 values for 4 columns
Я понимаю, что в общем, вы используете executemany
набивать исходные значения в БД настолько эффективно, насколько это возможно, и с этим в виду, вы вообще хотите номер значений, вставленных в соответствии с количеством столбцов.
Но что, если один или несколько столбцов «построены» через SQL и не имеют соответствующего входного значения?
Небольшой пример:
#!/usr/bin/env python2.7
import os
import sys
import sqlite3
from contextlib import closing
DB_FILE = 'test.sqlite'
with closing(sqlite3.connect(DB_FILE)) as db:
# First, some setup...
cursor = db.cursor()
cursor.execute('CREATE TABLE test (id TEXT PRIMARY KEY, a TEXT, b TEXT, c TEXT)')
sql = '''INSERT INTO test (id, a, b, c) VALUES (?, ?, ?, ?)'''
data = []
for i in range(5):
idStr = str(i)
data.append((idStr, 'a{}'.format(i), 'b{}'.format(i), 'c{}'.format(i)))
cursor.executemany(sql, data)
# Now, to exercise the problem:
# This does an 'upsert', but the same problem could occur in
# other circumstances.
sql = '''
INSERT OR REPLACE INTO test (id, a, b, c)
VALUES (
?,
(SELECT a,b FROM test WHERE id = ?),
?
)'''
data = []
for i in range(3,7):
idStr = str(i)
data.append((idStr, idStr, 'c{}'.format(i)))
cursor.executemany(sql, data)
db.commit()
При запуске этого, вы получите сообщение об ошибке, упомянутой в верхней части (3 values for 4 columns
).
Я полагаю, я мог бы обойти это, разбив SELECT a,b
на отдельные части SELECT a..., SELECT b...
, но есть ли лучший способ?
Приведенный пример невелик - на самом деле это могут быть 10 столбцов, которые мне теперь придется перечислить с их собственными предложениями (SELECT ...)
.
UPDATE 1 Это не относится к executemany
, как я первоначально думал. Такая же проблема имеет и запуск простого SQL вручную.
UPDATE 2 ответы ниже предлагают использовать SELECT
, а не VALUES
, однако, это не делает никакой работы, когда новая строка добавляемого (как в моем «upsert» случае), так как SELECT
возвращает нет строки в том, что дело.
Примечание: я удалил parens вокруг SELECT, поскольку он кажется недопустимым синтаксисом. – jwd
Похоже, что на самом деле это не работает, в случае, если это новый идентификатор ('INSERT' сторона' INSERT OR REPLACE'. Правильно? Если это так, это не работает для моего дела. – jwd