Pregunta

Me gustaría ejecutar una consulta PostgreSQL en Python usando PSYCOPG2, que filtra por una columna de tipo timestamp without timezone. Tengo una larga lista de valores permitidos para la marca de tiempo (en lugar de un rango) y PSYCOPG2 manejan convenientemente las matrices, por lo que pensé que esto debería funcionar:

SELECT somestuff
FROM mytable
WHERE thetimestamp = ANY (%(times)s)

los times El parámetro es una lista de datetime objetos. También he probado psycopg2.Timestamp(). Ambos se traducen a WHERE thetimestamp = ANY (ARRAY['2009-07-06T00:00:00', '2009-07-07T00:00:00', ...]) Y desafortunadamente eso falla con el siguiente error:

operator does not exist: timestamp without time zone = text
LINE 3: WHERE thetimestamp = ANY (ARRAY['2009-07-06T00:00:00', '2009-07-07T00:00:00', ...]
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

También confirmé esto en Pgadmin, por lo que no es solo PSYCOPG2. Lo que parece estar sucediendo es que Postgres no convertirá implícitamente una variedad de cuerdas en una variedad de marcas de tiempo. Convertirá una sola cadena fina y la matriz funciona bien si agrego explícitamente ::timestamp a cada elemento en Pgadmin, pero no sé cómo hacerlo en PsyCopg2.

¿Cuál es la mejor manera de hacer esto, aparte de olvidar los parámetros DB-API y simplemente construir la larga cadena de marcas de tiempo manualmente? ¿Hay alguna forma de que pueda lanzarlo al tipo correcto?

¿Fue útil?

Solución

Pruébelo así:

SELECT somestuff
FROM mytable
WHERE thetimestamp = ANY (%(times)s::timestamp[])

Otros consejos

Si usa PSYCOPG2 versión 2.2.0 o más nuevo, su código original debería funcionar, si envuelve los valores en Timestamp() constructores, como sugeriste.

La razón por la que no funcionó antes fue un error en la implementación de PSYCOPG2. La solución sugerida era insertar moldes explícitos en el SQL, como se sugiere en otra respuesta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top