So geben Sie den PSYCOPG2 -Parameter für ein Array für Zeitstempel an (DateTimes)
-
22-09-2019 - |
Frage
Ich möchte eine Postgresql -Abfrage in Python mit Psycopg2 ausführen, die nach einer Typsspalte filtert timestamp without timezone
. Ich habe eine lange Liste der zulässigen Werte für den Zeitstempel (anstelle eines Bereichs) und Psycopg2 verarbeitet bequem Arrays, daher dachte ich, dass dies funktionieren sollte:
SELECT somestuff
FROM mytable
WHERE thetimestamp = ANY (%(times)s)
Das times
Parameter ist eine Liste von datetime
Objekte. Ich habe es auch versucht psycopg2.Timestamp()
. Sie haben beide übersetzt WHERE thetimestamp = ANY (ARRAY['2009-07-06T00:00:00', '2009-07-07T00:00:00', ...])
Und leider fällt dies mit dem folgenden Fehler fehl:
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.
Ich habe dies auch in Pgadmin bestätigt, also ist es nicht nur psycopg2. Es scheint, dass Postgres eine Reihe von Strings nicht implizit in eine Reihe von Zeitstempeln umwandeln. Es wird eine einzelne Zeichenfolge fein konvertieren und das Array funktioniert einwandfrei, wenn ich explizit hinzufüge ::timestamp
Zu jedem Element in Pgadmin, aber ich weiß nicht, wie man das in Psycopg2 macht.
Was ist der beste Weg, dies zu tun, außer das Vergessen von DB-API-Parametern und einfach manuell die lange Reihe von Zeitstempeln zu erstellen? Gibt es eine Möglichkeit, es auf den richtigen Typ zu bringen?
Lösung
Versuchen Sie es so:
SELECT somestuff
FROM mytable
WHERE thetimestamp = ANY (%(times)s::timestamp[])
Andere Tipps
Wenn Sie PSYCOPG2 Version 2.2.0 oder neuer verwenden, sollte Ihr ursprünglicher Code funktionieren, wenn Sie die Werte in einwickeln Timestamp()
Konstruktoren, wie Sie vorgeschlagen haben.
Der Grund, warum es vorher nicht funktionierte, war ein Fehler in der Psycopg2 -Implementierung. Die vorgeschlagene Problemumgehung bestand darin, explizite Abgüsse in die SQL einzufügen, wie in einer anderen Antwort vorgeschlagen.