Python / psycopg2 WHERE IN declaración


81

¿Cuál es el método correcto para que la lista (countryList) esté disponible a través de% s en la declaración SQL?

# using psycopg2
countryList=['UK','France']

sql='SELECT * from countries WHERE country IN (%s)'
data=[countryList]
cur.execute(sql,data)

Tal como está ahora, se produce un error después de intentar ejecutar "DONDE el país en (ARRAY [...])". ¿Hay alguna forma de hacer esto que no sea mediante la manipulación de cuerdas?

Gracias

Respuestas:


133

Para el INoperador, desea una tupla en lugar de una lista y elimine los paréntesis de la cadena SQL.

# using psycopg2
data=('UK','France')

sql='SELECT * from countries WHERE country IN %s'
cur.execute(sql,(data,))

Durante la depuración, puede verificar que el SQL esté construido correctamente con

cur.mogrify(sql, (data,))

¡Gracias por la rápida respuesta!
Matt

1
Si tiene problemas incluso después de leer esta respuesta, vuelva a leerla muy lentamente. Es una tupla de tuplas y debes eliminar los parans alrededor de% s si los tienes allí. Esto me hizo tropezar porque una prueba mía más simple usó solo un valor y todo funcionó. Simplemente siga esto exactamente como Bryan lo escribió.
zachaysan

40

Para explicar un poco la respuesta y abordar los parámetros con nombre, y convertir listas en tuplas:

countryList = ['UK', 'France']

sql = 'SELECT * from countries WHERE country IN %(countryList)s'

cur.execute(sql, { # You can pass a dict for named parameters rather than a tuple. Makes debugging hella easier.
    'countryList': tuple(countryList), # Converts the list to a tuple.
})

1
Gracias por el consejo sobre pasar un dictamen. Eso es mucho mejor.
Jack

¿Se puede implementar esto con múltiples cláusulas WHERE x IN y múltiples listas en el diccionario?
Odisseo

1
Corrección: @Odisseo Sí, con el todopoderoso OR. Por ejemplo:cur.execute("SELECT * FROM table WHERE col IN %(list1)s OR col IN %(list2)s", {'list1': tuple(1,2,3), 'list2' = tuple(4,5,6)})
Joshua Burns

12

Puede usar una lista de Python directamente como se muestra a continuación. Actúa como el operador IN en SQL y también maneja una lista en blanco sin arrojar ningún error.

data=['UK','France']
sql='SELECT * from countries WHERE country = ANY (%s)'
cur.execute(sql,(data,))

fuente: http://initd.org/psycopg/docs/usage.html#lists-adaptation


También puede usar la respuesta aceptada pero con cur.execute(sql, (tuple(data),))
Adam Hughes
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.