Как указать параметр psycopg2 для массива для временных метров (Datetimes)
-
22-09-2019 - |
Вопрос
Я хотел бы запустить запрос PostgreSQL в Python, используя PSYCOPG2, который фильтрует столбец типа timestamp without timezone
. Анкет У меня есть длинный список разрешенных значений для метки времени (а не диапазона) и PSYCOPG2 удобно обрабатывает массивы, поэтому я подумал, что это должно работать:
SELECT somestuff
FROM mytable
WHERE thetimestamp = ANY (%(times)s)
А times
параметр - это список datetime
объекты. Я тоже пробовал psycopg2.Timestamp()
. Анкет Они оба переводится как WHERE thetimestamp = ANY (ARRAY['2009-07-06T00:00:00', '2009-07-07T00:00:00', ...])
И, к сожалению, это не удается со следующей ошибкой:
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.
Я также подтвердил это и в Pgadmin, так что это не только psycopg2. Кажется, что происходит то, что Postgres не будет косвенно преобразовать массив струн в массив временных метров. Он преобразует штраф в одной строке, а массив работает нормально, если я явно добавлю ::timestamp
каждому элементу в PGADMIN, но я не знаю, как это сделать в PSYCOPG2.
Как лучше всего это сделать, кроме того, что забыть параметры DB-API и просто создание длинной цепочки временных метров вручную? Есть ли способ, которым я могу заставить его поднять на правильный тип?
Решение
Попробуйте так:
SELECT somestuff
FROM mytable
WHERE thetimestamp = ANY (%(times)s::timestamp[])
Другие советы
Если вы используете PSYCOPG2 версию 2.2.0 или новее, ваш исходный код должен работать, если вы оберните значения в Timestamp()
конструкторы, как вы предложили.
Причиной того, что это не сработало раньше, была ошибка в реализации PSYCOPG2. Предлагаемый обходной путь состоял в том, чтобы вставить явные отливки в SQL, как было предложено в другом ответе.