私はPythonでexecutemany
を使っていくつかの行を移植しようとしています。Python + sqlite3:executemanyの値が "constructed"
sqlite3.OperationalError: 3 values for 4 columns
は、私は一般的に、あなたは、できるだけ効率的にDBに生の値を詰め込むためにexecutemany
を使用することを理解し、そのことを念頭に置いて、あなたは一般的に数をしたい:
しかし、私は取得しています列の数と一致するように挿入された値。
しかし、1つ以上の列が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
、しかし、これは、新しい行がSELECT
返すので、(私の「アップサート」の場合のように)追加されるいかなる作業もしないことに行ありません場合。
注:それは無効な構文だと思われるので、SELECTの周りに敬遠してください。 – jwd
これは新しいID(INSERTまたはREPLACEのINSERT側)が実際には機能しないようですが、そうであれば私の場合は機能しません – jwd