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?

85
demandé sur User12345 2008-11-12 14:18:32

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)
79
répondu bobince 2008-11-12 12:30:10

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))
19
répondu Blair Conrad 2017-05-23 12:03:05

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)

enter image description here

j'espère que cela a aidé !!!

18
répondu allsyed 2016-11-22 09:01:19

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 )

10
répondu gimel 2017-05-23 11:47:23

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))
6
répondu jimhark 2010-11-21 21:35:55

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)+'"'))
1
répondu Ximix 2014-11-26 09:43:32

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(']',')') )
1
répondu pgalilea 2016-08-18 18:02:23

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),))
0
répondu Roland Mechler 2018-06-28 22:08:31

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)
-1
répondu Amirhos Imani 2018-09-18 20:13:29