2

executemanyPython で使用して、いくつかの行にデータを入力しようとしています。

しかし、私は得ています:

sqlite3.OperationalError: 3 values for 4 columns

executemany一般に、生の値を可能な限り効率的にDBに詰め込むために使用していることを理解しています。それを念頭に置いて、通常、挿入される値の数を列の数と一致させたいと考えています。

しかし、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 1executemany私が最初に考えていたように、これはに固有のものではありません。単純な SQL を手動で実行しても同じ問題があります。

UPDATE 2以下の回答では、SELECTではなくa を使用することをお勧めしますVALUESが、新しい行が追加されている場合 (私の「アップサート」の場合のように)、これは機能しませSELECTん。その場合、 は行を返さないためです。

4

2 に答える 2

0

はい!もっと良い方法があります!VALUES句をSELECTステートメントに置き換えてください。

クエリは次のようになります。

INSERT OR REPLACE INTO test (id, a, b, c)
    SELECT ?, a, b, ? FROM test WHERE id = ?

dataパラメータの順序が異なるため、リストを変更することを忘れないでください。

于 2016-12-19T19:52:22.660 に答える