【问题标题】:How to specify psycopg2 parameter for an array for timestamps (datetimes)如何为时间戳(日期时间)数组指定 psycopg2 参数
【发布时间】:2024-01-21 09:47:01
【问题描述】:

我想使用 psycopg2 在 Python 中运行 PostgreSQL 查询,它按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 参数并手动构建一长串时间戳之外,最好的方法是什么?有什么办法可以让它转换为正确的类型?

【问题讨论】:

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


    【解决方案1】:

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

    它之前不起作用的原因是 psycopg2 实现中的错误。建议的解决方法是在 SQL 中插入显式转换,正如另一个答案中所建议的那样。

    【讨论】:

      【解决方案2】:

      试试这样:

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

      【讨论】: