Tengo una lista de python, digamos l
l = [1,5,8]
Quiero escribir una consulta SQL para obtener los datos de todos los elementos de la lista, digamos
select name from students where id = |IN THE LIST l|
¿Cómo logro esto?
Hasta ahora, las respuestas han estado creando los valores en una cadena SQL simple. Eso está absolutamente bien para los enteros, pero si quisiéramos hacerlo por cadenas obtenemos el problema de escape.
Aquí hay una variante que usa una consulta parametrizada que funcionaría 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)
','.join(placeholder * len(l))
sería un poco más corto mientras aún legible en mi humilde opinión([placeholder]*len(l))
en el caso general ya que el marcador de posición puede tener varios caracteres.cursor.execute(f'SELECT name FROM students WHERE id IN ({','.join('?' for _ in l)})', l)
. @bobince, también debe comentar en su solución que usar?
es la forma segura de evitar la inyección de SQL. Aquí hay muchas respuestas que son vulnerables, básicamente cualquiera que concatene cadenas en python.La forma más fácil es convertir
tuple
primero la listafuente
No lo complique, la solución para esto es simple.
Espero que esto haya ayudado !!!
fuente
l
solo contiene un elemento, terminarás conid IN (1,)
. Que es un error de sintaxis.sqlite3
. ¿Contra qué biblioteca probaste esto?El SQL que quieres es
Si quieres construir esto desde la pitón, puedes usar
La función de mapa transformará la lista en una lista de cadenas que se pueden unir mediante comas utilizando el método str.join .
Alternativamente:
si prefiere expresiones generadoras 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
Generado por
fuente
string. únete a los valores de la lista separados por comas y usa el operador de formato para formar una cadena de consulta.
(Gracias, blair-conrad )
fuente
%
uso aquí es simplemente formato de cadena Python.Me gusta la respuesta de bobince:
Pero me di cuenta de esto:
Se puede reemplazar con:
Encuentro esto más directo si es menos inteligente y menos general. Aquí
l
se requiere tener una longitud (es decir, referirse a un objeto que define un__len__
método), lo que no debería ser un problema. Pero el marcador de posición también debe ser un solo personaje. Para admitir un uso de marcador de posición de varios caracteres:fuente
Solución para la respuesta @umounted, porque eso rompió con una tupla de un elemento, ya que (1,) no es SQL válido:
Otra solución para la cadena sql:
fuente
Esto debería solucionar tu problema.
fuente
Si está utilizando PostgreSQL con la biblioteca Psycopg2, puede dejar que su adaptación de tupla haga toda la interpolación de escape y cadena por usted, por ejemplo:
es decir, solo asegúrese de pasar el
IN
parámetro como atuple
. si es unlist
puede usar la= ANY
sintaxis de matriz :tenga en cuenta que ambos se convertirán en el mismo plan de consulta, por lo que debe usar el que sea más fácil. por ejemplo, si su lista viene en una tupla, use la primera, si están almacenadas en una lista, use la segunda.
fuente
Por ejemplo, si desea la consulta sql:
Qué pasa:
fuente
Una solución más simple:
fuente
La
:var
notación parece más simple. (Python 3.7)fuente
Esto utiliza la sustitución de parámetros y se ocupa del caso de la lista de valores únicos:
fuente