2009-12-30 4 views
9

Je voudrais exécuter une requête PostgreSQL en Python en utilisant psycopg2, qui filtre par une colonne de type timestamp without timezone. J'ai une longue liste de valeurs autorisées pour l'horodatage (plutôt que d'une plage) et psycopg2 gère convenablement les tableaux, donc je pensais que cela devrait fonctionner:Comment spécifier un paramètre psycopg2 pour un tableau d'horodatage (datetimes)

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

Le paramètre times est une liste de datetime objets. J'ai également essayé psycopg2.Timestamp(). Ils ont tous deux se traduit par WHERE thetimestamp = ANY (ARRAY['2009-07-06T00:00:00', '2009-07-07T00:00:00', ...]) et, malheureusement, qui échoue avec l'erreur suivante:

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. 

Je l'ai confirmé dans pgAdmin aussi bien, il est donc pas seulement psycopg2. Ce qui semble se passer est que Postgres ne convertira pas implicitement un tableau de chaînes en un tableau d'horodatages. Il convertira une seule chaîne et le tableau fonctionnera correctement si j'ajoute explicitement ::timestamp à chaque élément dans pgAdmin, mais je ne sais pas comment le faire dans psycopg2.

Quelle est la meilleure façon d'y parvenir, autre que d'oublier les paramètres DB-API et de construire manuellement la longue chaîne d'horodatages? Y a-t-il un moyen que je peux obtenir pour lancer le bon type?

Répondre

12

Essayez comme ceci:

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

Si vous utilisez la version 2.2.0 ou plus récent psycopg2, votre code d'origine devrait fonctionner, si vous enveloppez les valeurs Timestamp() constructeurs, comme vous le suggérez.

La raison pour laquelle cela n'a pas fonctionné auparavant était un bug dans l'implémentation de psycopg2. La solution de contournement suggérée consistait à insérer des conversions explicites dans le SQL, comme suggéré dans une autre réponse.

Questions connexes