it-swarm.com.de

SQLite-Parameterersetzungsproblem

Bei Verwendung von SQLite3 mit Python 2.5 versuche ich, eine Liste zu durchlaufen und die Gewichtung eines Elements aus der Datenbank basierend auf dem Namen des Elements zu ziehen.

Ich habe versucht, das "?" Parameterersetzung vorgeschlagen, um SQL-Injektionen zu verhindern, aber es funktioniert nicht. Zum Beispiel, wenn ich verwende:

for item in self.inventory_names:
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", item)
    self.cursor.close()

Ich bekomme den Fehler:

sqlite3.ProgrammingError: Falsche Anzahl der gelieferten Bindungen. Die aktuelle Anweisung verwendet 1, und es werden 8 angegeben.

Ich glaube, dass dies irgendwie auf die anfängliche Erstellung der Datenbank zurückzuführen ist. Das von mir erstellte Modul, das die Datenbank tatsächlich erstellt, hat 8 Bindungen.

cursor.execute("""CREATE TABLE Equipment 
    (id INTEGER PRIMARY KEY, 
    name TEXT,
    price INTEGER, 
    weight REAL, 
    info TEXT, 
    ammo_cap INTEGER, 
    availability_west TEXT,
    availability_east TEXT)""")

Wenn ich jedoch die weniger sichere "% s" - Ersetzung für jeden Elementnamen verwende, funktioniert das einwandfrei. So wie:

for item in self.inventory_names:
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = '%s'" % item)
    self.cursor.close()

Ich kann nicht herausfinden, warum ich denke, ich habe 8 Bindins, wenn ich nur eines anrufe. Wie kann ich es reparieren?

55
crystalattice

Die Cursor.execute()-Methode erwartet eine Sequenz als zweiten Parameter. Sie geben eine Zeichenfolge an, die zufällig 8 Zeichen lang ist.

Verwenden Sie stattdessen das folgende Formular:

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", [item])

Referenz zur Python-Bibliothek: sqlite3 Cursor-Objekte .

126
ddaa

Ich habe einen halben Tag damit verbracht herauszufinden, warum so etwas einen Fehler hervorruft:

cursor.execute("SELECT * from ? WHERE name = ?", (table_name, name))

nur um herauszufinden, dass die Tabellennamen nicht parametrisiert werden können . Ich hoffe, das hilft anderen Menschen, Zeit zu sparen.

49
ccpizz

Das Argument von cursor.execute, das die Werte repräsentiert, die Sie in die Datenbank einfügen müssen, sollte ein Tuple (eine Sequenz) sein. Betrachten Sie jedoch dieses Beispiel und sehen Sie, was passiert:

>>> ('jason')
'jason'

>>> ('jason',)
('jason',)

Das erste Beispiel wird stattdessen in eine Zeichenfolge ausgewertet. Die korrekte Darstellungsweise von einwertigem Tupel ist also wie in der zweiten Auswertung. Wie auch immer, der Code unten, um Ihren Fehler zu beheben.

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item,))

Wenn Sie die Argumente cursor.execute als Zeichenfolgen angeben (was Sie gerade tun), führt dies zur ersten Auswertung im Beispiel und zu dem Fehler, den Sie erhalten.

22
jgtumusiime

hast du das probiert :

for item in self.inventory_names:
    t = (item,)
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", t)
    self.cursor.close()

cursor.execute () erwartet eine Sequenz (Liste, Tuple) als zweiten Parameter. (-> ddaa)

2
Blauohr

Zitieren (ist das, was die Eltern bedeuten?) Das? mit parens scheint für mich zu arbeiten. Ich versuchte immer wieder mit (wörtlich) '?' aber ich bekam weiter

ProgrammingError: Falsche Anzahl der gelieferten Bindungen. Die aktuelle Anweisung verwendet 0, und es werden 1 angegeben.

Wenn ich es tat:

Fakten von Factoids auswählen WO Schlüssel LIKE (?)

anstatt:

WÄHLEN SIE Fakt aus Faktoiden WO WO LIKE '?'

Es funktionierte.

Ist das eine Python 2.6 Sache?

1
kjikaqawej

Das Modul sqlite3 unterstützt zwei Arten von Platzhaltern für Parameter:

qmark style

Verwenden Sie einen oder mehrere ?, um die Position jedes Parameters zu markieren, und geben Sie eine Liste oder ein Tuple von Parametern an. Z.B.:

curs.execute("SELECT weight FROM Equipment WHERE name = ? AND price = ?",
             ['lead', 24])

benannter Stil

Verwenden Sie :par-Platzhalter für jeden benannten Parameter und geben Sie ein Diktat an. Z.B.:

curs.execute("SELECT weight FROM Equipment WHERE name = :name AND price = :price",
             {name: 'lead', price: 24})

Die benannten Stilparameter haben den Vorteil, dass Sie sich nicht um die Reihenfolge der Parameter kümmern müssen. Jeder :par kann in großen/komplexen SQL-Abfragen mehrfach verwendet werden.

0
Mike T

jedes Element der Elemente muss ein Tuple sein. Die Namen sehen etwa so aus:

names = ['Joe', 'Bob', 'Mary']

sie sollten Folgendes tun:

for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item, ))

indem Sie (item,) verwenden, machen Sie ihn anstelle eines Strings zu einem Tuple.

0
Joey Nelson