如何为时间戳(日期时间)指定数组的psycopg2参数

时间:2009-12-30 05:42:28

标签: python postgresql timestamp psycopg2 python-db-api

我想使用psycopg2在Python中运行PostgreSQL查询,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不会隐式地将字符串数组转换为时间戳数组。如果我向pgAdmin中的每个元素显式添加::timestamp,它会很好地转换单个字符串并且数组工作正常,但我不知道如何在psycopg2中执行此操作。

除了忘记DB-API参数以及只是手动构建长串时间戳之外,最好的方法是什么?有什么方法可以让它投射到正确的类型吗?

2 个答案:

答案 0 :(得分:12)

试试这样:

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

答案 1 :(得分:3)

如果您使用psycopg2 2.2.0或更高版本,如果您按照建议将值包装在Timestamp()构造函数中,原始代码应该可以正常工作。

之前没有用的原因是psycopg2实现中的一个错误。建议的解决方法是在SQL中插入显式强制转换,如另一个答案所示。