2008-11-12 74 views

Respuesta

68

respuestas hasta ahora han sido los valores de plantillas en una cadena SQL sin formato. Eso está absolutamente bien para los enteros, pero si quisiéramos hacerlo por cadenas, obtendríamos el problema del escape.

Aquí es una variante utilizando una consulta parametrizada que funcione para ambos:

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) 
+4

'','. join (marcador de posición * len (l))' sería un poco más corto mientras aún es legible imho – ThiefMaster

+5

@Thiefmaster: sí, tendría que ser '([placeholder] * len (l)) 'en el caso general, ya que el marcador de posición puede tener múltiples caracteres. – bobince

+0

@bobince en mi caso he asignado una variable a = 'john' yb = 'nieve' y la he almacenado en una tupla con el nombre get = ['a, b'] y realicé la misma consulta. Al hacer esto, obtuve el erroy, es decir, Error de tipo: no todos los argumentos se convirtieron durante el formateo de cadenas. ¿Cómo se supone que lo solfeo? – TechJhola

10

string.join la lista guarda los valores separados por comas, y utiliza format operator para formar una cadena de consulta.

myquery = "select name from studens where id in (%s)" % ",".join(map(str,mylist)) 

(Gracias, blair-conrad)

17

El SQL que desea es

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

Si desea construir este de la pitón se podría utilizar

l = [1, 5, 8] 
sql_query = 'select name from studens where id in (' + ','.join(map(str, l)) + ')' 

La función map transformará la lista en una lista de cadenas que se pueden unir mediante com mas usando el método str.join.

alternativa:

l = [1, 5, 8] 
sql_query = 'select name from studens where id in (' + ','.join((str(n) for n in l)) + ')' 

si lo prefiere generator expressions a la función de mapa.

ACTUALIZACIÓN: S. Lott menciona en los comentarios que los enlaces Python SQLite no admiten secuencias. En ese caso, es posible que desee

select name from studens where id = 1 or id = 5 or id = 8 

Generado por

sql_query = 'select name from studens where ' + ' or '.join(('id = ' + str(n) for n in l)) 
+1

:-(El enlace Python SQLite no es compatible con las secuencias –

+0

Oh, no me di cuenta. Por otra parte, no me di cuenta de que íbamos a buscar una solución SQLite. –

+0

Lo sentimos, no sugiriendo o implicando SQLite - - Sólo triste que las vinculaciones para las listas no funcionan allí. –

6

me gusta la respuesta 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) 

Pero me di cuenta de esto:

placeholders= ', '.join(placeholder for unused in l) 

puede ser reemplazado por:

placeholders= ', '.join(placeholder*len(l)) 

Encuentro esto más directo si menos inteligente y menos general. Aquí l se requiere tener una longitud (es decir, hacer referencia a un objeto que define un método __len__), lo que no debería ser un problema. Pero el marcador de posición también debe ser un solo carácter.Para apoyar un carácter multi-marcador de posición uso:

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

Solución para @umounted respuesta, debido a que rompieron con una tupla de un solo elemento, ya que (1,) no es válida 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,)] 

otra solución para la cadena SQL:

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

Esta no es la mejor solución debido a la inyección sql. – Anurag

1

por ejemplo, si desea que la consulta SQL:

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

¿Qué hay de:

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

Dont complican, solución para esto es 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

espero que esto ayudó !!!

+2

Esto no funciona si 'l' solo contiene un elemento, usted terminará con' id IN (1,) '. Que es un error de sintaxis – renstrm

+0

Si solo se trata de un elemento, IN no es el operador que está buscando.OP claramente no lo hace; t. – allsyed

+2

Si solo contiene 1 elemento, asegúrese de que sea una tupla y FUNCIONE. Esta solución es más clara en mi opinión que la aceptada. –

Cuestiones relacionadas