web-dev-qa-db-fra.com

liste python dans une requête sql en tant que paramètre

J'ai une liste de python, disons l

l = [1,5,8]

Je veux écrire une requête SQL pour obtenir les données pour tous les éléments de la liste, disons

select name from students where id = |IN THE LIST l|

Comment puis-je accomplir cela?

90
Mohit Ranka

Les réponses ont jusqu'à présent modélisé les valeurs dans une chaîne SQL simple. C'est tout à fait correct pour les entiers, mais si nous voulions le faire pour les chaînes, nous avons le problème qui nous échappe.

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)
85
bobince

Le SQL que vous voulez est

select name from studens where id in (1, 5, 8)

Si vous voulez construire ceci à 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 pouvant être collées par des virgules à l'aide de la méthode str.join .

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 générer des expressions à la fonction map.

UPDATE: S. Lott mentionne dans les commentaires que les liaisons Python SQLite ne prennent pas en charge les séquences. Dans ce cas, vous voudrez peut-être

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))
21
Blair Conrad

Ne compliquez pas les choses, la solution 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
allsyed

string.join la liste des valeurs séparées par des virgules et utilisez l'opérateur 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
gimel

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 si moins intelligent et moins général. Ici, l doit avoir une longueur (c'est-à-dire faire référence à un objet qui définit une méthode __len__), ce qui ne devrait pas poser de problème. Mais l'espace réservé doit également être un seul caractère. Pour prendre en charge l'utilisation d'un espace réservé multi-caractères:

placeholders= ', '.join([placeholder]*len(l))
6
jimhark

Le moyen le plus simple est de transformer la liste en Tuple en premier

t = Tuple(l)
query = "select name from studens where id IN {}".format(t)
4
Amirhos Imani

Solution pour la réponse @umounted, parce que cela s'est cassé avec un tuple à un élément, puisque (1,) n'est pas valide SQL .:

>>> 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 sql string:

cursor.execute("select id from test where id in (%s)" % ('"'+'", "'.join(l)+'"'))
2
Ximix

Par exemple, si vous voulez la requête SQL:

select name from studens where id in (1, 5, 8)

Qu'en est-il de:

my_list = [1, 5, 8]
cur.execute("select name from studens where id in %s" % repr(my_list).replace('[','(').replace(']',')') )
1
pgalilea

une solution plus simple:

lst = [1,2,3,a,b,c]

query = f"""SELECT * FROM table WHERE IN {str(lst)[1:-1}"""
0
Omar Omeiri
placeholders= ', '.join("'{"+str(i)+"}'" for i in range(len(l)))
query="select name from students where id (%s)"%placeholders
query=query.format(*l)
cursor.execute(query)

Cela devrait résoudre votre problème.

0
Rishabh Jain

Ceci utilise la substitution de paramètre et prend en charge le cas de liste de valeurs 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
Roland Mechler