sqlite3.ProgrammingError: Falsche Anzahl der bereitgestellten Bindungen. Die aktuelle Anweisung verwendet 1, und es werden 74 geliefert

184
def insert(array):
    connection=sqlite3.connect('images.db')
    cursor=connection.cursor()
    cnt=0
    while cnt != len(array):
            img = array[cnt]
            print(array[cnt])
            cursor.execute('INSERT INTO images VALUES(?)', (img))
            cnt+= 1
    connection.commit()
    connection.close()

Ich kann nicht herausfinden, warum dies mir den Fehler gibt. Die tatsächliche Zeichenfolge, die ich einzufügen versuche, ist 74 Zeichen lang. Sie lautet: "/ gifs / epic-fail-photos-there-i-fixed-it-aww-man-the -Reifendruck-niedrig.gif "

Ich habe versucht, str (array [cnt]) vor dem Einfügen zu verwenden, aber das gleiche Problem tritt auf. Die Datenbank hat nur eine Spalte, bei der es sich um einen TEXT-Wert handelt.

Ich bin schon seit Stunden dabei und kann nicht herausfinden, was los ist.

AB49K
quelle

Antworten:

377

Sie müssen eine Sequenz übergeben, aber Sie haben das Komma vergessen, um Ihre Parameter zu einem Tupel zu machen:

cursor.execute('INSERT INTO images VALUES(?)', (img,))

Ohne Komma (img)ist es nur ein gruppierter Ausdruck, kein Tupel, und daher wird die imgZeichenfolge als Eingabesequenz behandelt. Wenn diese Zeichenfolge 74 Zeichen lang ist, sieht Python dies als 74 separate Bindungswerte, die jeweils ein Zeichen lang sind.

>>> len(img)
74
>>> len((img,))
1

Wenn Sie es leichter lesen können, können Sie auch ein Listenliteral verwenden:

cursor.execute('INSERT INTO images VALUES(?)', [img])
Martijn Pieters
quelle
37
Wir sind viele fortgeschrittene Programmierer, die diesen Fehler gemacht haben, also müssen Sie sich nicht dumm fühlen. :)
MrGumble
6
Das hat mich auch gebissen. Wenn "fortgeschrittene Codierer" davon getäuscht werden, bedeutet dies, dass es nicht intuitiv ist. IMHO wäre es natürlicher, wenn execute () einen einzelnen Wert anstelle eines einwertigen Tupels annehmen würde, wenn es nur einen gibt? in der Abfrage. Trotzdem danke für den Hinweis!
Laryx Decidua
5
@ user465139: Der %Operator auf strmacht diese Art von Magie - er behandelt ein Tupel als mehrere Werte, aber ein str(oder eine andere Art von iterierbarem) Wert als einen einzelnen Wert. Aber das führt weitaus häufiger zu Verwirrung als zu einer Lösung, weshalb fast nichts anderes in der stdlib diese Art von Magie versucht.
Abarnert
2
cursor.execute(sql,array)

Nimmt nur zwei Argumente.
Es wird das "Array" -Objekt iterieren und übereinstimmen? in der SQL-Zeichenfolge.
(mit Sanity Checks zur Vermeidung von SQL-Injektionen)

Punnerud
quelle