Domanda

Vorrei eseguire una query PostgreSQL in Python usando Psycopg2, che filtra per una colonna di tipo timestamp without timezone. Ho un lungo elenco di valori consentiti per il timestamp (anziché un intervallo) e Psycopg2 gestisce comodamente array, quindi ho pensato che questo dovesse funzionare:

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

Il times Il parametro è un elenco di datetime oggetti. Ho anche provato psycopg2.Timestamp(). Entrambi si traducono in WHERE thetimestamp = ANY (ARRAY['2009-07-06T00:00:00', '2009-07-07T00:00:00', ...]) E sfortunatamente questo fallisce con il seguente errore:

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.

L'ho confermato anche in pgadmin, quindi non è solo Psycopg2. Ciò che sembra accadere è che Postgres non convertirà implicitamente una serie di stringhe in una serie di timestamp. Convertirà una sola stringa e l'array funziona bene se aggiungo esplicitamente ::timestamp Ad ogni elemento in PGADMIN, ma non so come farlo in Psycopg2.

Qual è il modo migliore per farlo, oltre a dimenticare i parametri DB-API e costruire manualmente la lunga serie di timestamp? C'è un modo per farlo lanciare al tipo corretto?

È stato utile?

Soluzione

Provalo in questo modo:

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

Altri suggerimenti

Se si utilizza PsyCOPG2 versione 2.2.0 o più recente, il codice originale dovrebbe funzionare, se si avvolgono i valori in Timestamp() costruttori, come hai suggerito.

Il motivo per cui non funzionava prima era un bug nell'implementazione di Psycopg2. La soluzione suggerita era quella di inserire cast espliciti nel SQL, come suggerito in un'altra risposta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top