Python / psycopg2 WHERE IN-Anweisung

80

Was ist die richtige Methode, um die Liste (countryList) über% s in der SQL-Anweisung verfügbar zu machen?

# using psycopg2
countryList=['UK','France']

sql='SELECT * from countries WHERE country IN (%s)'
data=[countryList]
cur.execute(sql,data)

So wie es jetzt ist, tritt ein Fehler auf, nachdem versucht wurde, "WHERE country in (ARRAY [...])" auszuführen. Gibt es eine andere Möglichkeit als die Manipulation von Strings?

Vielen Dank

Matt
quelle

Antworten:

129

Für den INOperator möchten Sie ein Tupel anstelle einer Liste und Klammern aus der SQL-Zeichenfolge entfernen.

# using psycopg2
data=('UK','France')

sql='SELECT * from countries WHERE country IN %s'
cur.execute(sql,(data,))

Während des Debuggens können Sie überprüfen, ob SQL korrekt mit erstellt wurde

cur.mogrify(sql, (data,))
Bryan
quelle
Danke für die schnelle Antwort!
Matt
Wenn Sie auch nach dem Lesen dieser Antwort Probleme haben, lesen Sie sie sehr langsam erneut. Es ist ein Tupel von Tupeln und Sie müssen die Parans um die% s entfernen, wenn Sie sie dort haben. Das hat mich gestolpert, weil ein einfacherer Test von mir nur einen einzigen Wert verwendet hat und alles funktioniert hat. Befolgen Sie dies genau so, wie Bryan es geschrieben hat.
Zachaysan
40

Um die Antwort ein wenig zu erläutern, benannte Parameter zu adressieren und Listen in Tupel umzuwandeln:

countryList = ['UK', 'France']

sql = 'SELECT * from countries WHERE country IN %(countryList)s'

cur.execute(sql, { # You can pass a dict for named parameters rather than a tuple. Makes debugging hella easier.
    'countryList': tuple(countryList), # Converts the list to a tuple.
})
Joshua Burns
quelle
1
Vielen Dank für den Tipp zur Abgabe eines Diktats. Das ist viel viel besser.
Jack
Kann dies mit mehreren WHERE x IN-Klauseln und mehreren Listen im Wörterbuch implementiert werden?
Odisseo
1
Korrektur: @Odisseo Ja, mit dem allmächtigen OP. ZB:cur.execute("SELECT * FROM table WHERE col IN %(list1)s OR col IN %(list2)s", {'list1': tuple(1,2,3), 'list2' = tuple(4,5,6)})
Joshua Burns
10

Sie können eine Python-Liste direkt wie folgt verwenden. Es verhält sich wie der IN-Operator in SQL und verarbeitet auch eine leere Liste, ohne einen Fehler auszulösen.

data=['UK','France']
sql='SELECT * from countries WHERE country = ANY (%s)'
cur.execute(sql,(data,))

Quelle: http://initd.org/psycopg/docs/usage.html#lists-adaptation

Praveenrajan27
quelle
Kann auch akzeptierte Antwort verwenden, aber mit cur.execute(sql, (tuple(data),))
Adam Hughes