Ich habe eine Python-Liste, sag ich
l = [1,5,8]
Ich möchte eine SQL-Abfrage schreiben, um beispielsweise die Daten für alle Elemente der Liste abzurufen
select name from students where id = |IN THE LIST l|
Wie schaffe ich das?
Bisher wurden die Werte in eine einfache SQL-Zeichenfolge umgewandelt. Das ist absolut in Ordnung für ganze Zahlen, aber wenn wir es für Strings tun wollten, bekommen wir das Escape-Problem.
Hier ist eine Variante mit einer parametrisierten Abfrage, die für beide funktioniert:
placeholder= '?' # For SQLite. See DBAPI paramstyle.
placeholders= ', '.join(placeholder for unused in l)
query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders
cursor.execute(query, l)
','.join(placeholder * len(l))
wäre etwas kürzer während noch lesbar imho([placeholder]*len(l))
im allgemeinen Fall sein, da der Platzhalter aus mehreren Zeichen bestehen kann.cursor.execute(f'SELECT name FROM students WHERE id IN ({','.join('?' for _ in l)})', l)
. @bobince, Sie sollten in Ihrer Lösung auch bemerken, dass die Verwendung?
der sichere Weg ist, um SQL-Injection zu vermeiden. Hier gibt es viele Antworten, die anfällig sind, im Grunde alle, die Zeichenfolgen in Python verketten.Am einfachsten ist es, die Liste an die
tuple
erste Stelle zu setzenquelle
Komplizieren Sie es nicht, die Lösung hierfür ist einfach.
Ich hoffe das hat geholfen !!!
quelle
l
nur ein Element enthalten istid IN (1,)
. Welches ist ein Syntaxfehler.sqlite3
. Mit welcher Bibliothek haben Sie das getestet?Das gewünschte SQL ist
Wenn Sie dies aus der Python konstruieren möchten, können Sie verwenden
Die Map- Funktion wandelt die Liste in eine Liste von Zeichenfolgen um, die mit der Methode str.join durch Kommas zusammengeklebt werden können .
Alternative:
Wenn Sie Generatorausdrücke der Kartenfunktion vorziehen .
AKTUALISIEREN: S. Lott erwähnt in den Kommentaren, dass die Python SQLite-Bindungen keine Sequenzen unterstützen. In diesem Fall möchten Sie vielleicht
Erstellt von
quelle
String.Join die Liste Wert durch Kommata getrennt, und verwenden Sie das Format Operator eine Abfrage - Zeichenfolge zu bilden.
(Danke, Blair-Conrad )
quelle
%
Wesen verwendet hier ist einfach nur Python - String formatiert wird .Ich mag die Antwort von Bobince:
Aber mir ist das aufgefallen:
Kann ersetzt werden durch:
Ich finde das direkter, wenn auch weniger klug und weniger allgemein. Hier
l
muss eine Länge vorhanden sein (dh auf ein Objekt verweisen, das eine__len__
Methode definiert ), was kein Problem sein sollte. Platzhalter müssen aber auch ein einzelnes Zeichen sein. So unterstützen Sie einen Platzhalter mit mehreren Zeichen:quelle
Lösung für @umounted Antwort, da dies mit einem Ein-Element-Tupel brach, da (1,) kein gültiges SQL ist:
Andere Lösung für SQL-Zeichenfolge:
quelle
Dies sollte Ihr Problem lösen.
quelle
Wenn Sie PostgreSQL mit der psycopg2 Bibliothek verwenden können Sie sein lassen Tupel Anpassung für Sie alle entkommen und String - Interpolation tun, zum Beispiel:
Stellen Sie einfach sicher, dass Sie den
IN
Parameter als übergebentuple
. Wenn es ein istlist
, können Sie die= ANY
Array-Syntax verwenden :Beachten Sie, dass beide in denselben Abfrageplan umgewandelt werden, sodass Sie nur den einfacheren verwenden sollten. Wenn Ihre Liste beispielsweise in einem Tupel vorliegt, verwenden Sie das erstere. Wenn sie in einer Liste gespeichert sind, verwenden Sie das letztere.
quelle
Wenn Sie beispielsweise die SQL-Abfrage möchten:
Wie wäre es mit:
quelle
eine einfachere Lösung:
quelle
Die
:var
Notation scheint einfacher. (Python 3.7)quelle
Dies verwendet die Parametersubstitution und kümmert sich um den Fall der Einzelwertliste:
quelle