liste python dans la requête sql comme paramètre
j'ai une liste de python, dites l
l = [1,5,8]
je veux écrire une requête sql pour récupérer les données de tous les éléments de la liste, dites
select name from students where id = |IN THE LIST l|
Comment faire?
9 réponses
les réponses jusqu'à présent ont été de tempérer les valeurs dans une chaîne SQL simple. C'est très bien pour les entiers, mais si nous voulions le faire pour les cordes, nous obtenons le problème d'évasion.
voici une variante utilisant une requête paramétrée qui fonctionnerait pour les deux:
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)
Le SQL que vous voulez est
select name from studens where id in (1, 5, 8)
si vous voulez construire cela à partir du python, vous pouvez utiliser
l = [1, 5, 8]
sql_query = 'select name from studens where id in (' + ','.join(map(str, l)) + ')'
la fonction map transformera la liste en une liste de chaînes qui peuvent être collées ensemble par des virgules en utilisant le str.joindre la méthode .
alternativement:
l = [1, 5, 8]
sql_query = 'select name from studens where id in (' + ','.join((str(n) for n in l)) + ')'
si vous préférez expressions du générateur à la fonction map.
UPDATE: S. Lott mentionne dans les commentaires que les fixations SQLite de Python ne supportent pas les séquences. Dans ce cas, vous pourriez vouloir
select name from studens where id = 1 or id = 5 or id = 8
généré par
sql_query = 'select name from studens where ' + ' or '.join(('id = ' + str(n) for n in l))
ne le compliquez pas, la Solution pour cela est simple.
l = [1,5,8]
l = tuple(l)
params = {'l': l}
cursor.execute('SELECT * FROM table where id in %(l)s',params)
j'espère que cela a aidé !!!
de la chaîne.joindre la liste des valeurs séparées par des virgules, et utiliser l'opérateur de format pour former une chaîne de requête.
myquery = "select name from studens where id in (%s)" % ",".join(map(str,mylist))
(Merci, blair-conrad )
j'aime la réponse de bobince:
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)
mais j'ai remarqué ceci:
placeholders= ', '.join(placeholder for unused in l)
peut être remplacé par:
placeholders= ', '.join(placeholder*len(l))
je trouve cela plus direct bien que moins intelligent et moins général. Ici l
est requis pour avoir une longueur (i.e. se référer à un objet qui définit une méthode __len__
), ce qui ne devrait pas être un problème. Mais l'espace réservé doit aussi être un caractère unique. Pour supporter un placeholder à plusieurs caractères use:
placeholders= ', '.join([placeholder]*len(l))
Solution pour @umounted réponse, parce que cela a cassé avec un tuple d'un élément, puisque (1,) N'est pas SQL valide.:
>>> random_ids = [1234,123,54,56,57,58,78,91]
>>> cursor.execute("create table test (id)")
>>> for item in random_ids:
cursor.execute("insert into test values (%d)" % item)
>>> sublist = [56,57,58]
>>> cursor.execute("select id from test where id in %s" % str(tuple(sublist)).replace(',)',')'))
>>> a = cursor.fetchall()
>>> a
[(56,), (57,), (58,)]
autre solution pour chaîne sql:
cursor.execute("select id from test where id in (%s)" % ('"'+'", "'.join(l)+'"'))
Par exemple, si vous voulez la requête sql:
select name from studens where id in (1, 5, 8)
Ce sujet:
my_list = [1, 5, 8]
cur.execute("select name from studens where id in %s" % repr(my_list).replace('[','(').replace(']',')') )
cela utilise la substitution de paramètre et prend soin du cas de la liste de valeur unique:
l = [1,5,8]
get_operator = lambda x: '=' if len(x) == 1 else 'IN'
get_value = lambda x: int(x[0]) if len(x) == 1 else x
query = 'SELECT * FROM table where id ' + get_operator(l) + ' %s'
cursor.execute(query, (get_value(l),))
la façon la plus facile est de tourner la liste en tuple
premier
t = tuple(l)
query = "select name from studens where id IN {}".format(t)