如何将 tz 感知的日期时间实例传递给 asyncpg?

问题描述 投票:0回答:1

当我明确地自己做所有事情时,我的查询工作正常:

# start_ts is of PostgreSQL type "timestamp with time zone" aka "timestamptz"
# start & end are datetime.datetime instances with tz=UTC
query += f"WHERE start_ts >= '{ str(start) }'::timestamptz AND start_ts < '{ str(end) }'::timestamptz"
await conn.fetch( query )

当我尝试将它们作为参数传递并让 asyncpg 代表我安全地将它们插入查询字符串时:

query += "WHERE start_ts >= $1::timestamptz AND start_ts < $2::timestamptz"
await conn.fetch( query, start, end )

我收到此错误:

CannotCoerceError: cannot cast type text[] to timestamp with time zone

我做错了什么?

PS - 我希望我能看到 asyncpg 发送 PostgreSQL 的实际查询,但我在文档或谷歌搜索中找不到有关如何启用它的任何内容。

python sql postgresql datetime asyncpg
1个回答
0
投票

您需要将值作为参数传递,以便 asyncpg 可以执行必要的类型转换,如以下示例脚本所示。 使用 f-strings 会绕过 asyncpg 的类型转换,如果您正在处理来自不受信任来源的数据,则会面临 SQL 注入的风险。

async def main():
    conn = await asyncpg.connect('postgresql:///so')

    now = datetime.datetime.now(tz=datetime.UTC)
    row = await conn.fetchrow("""SELECT $1::timestamptz as "timestamp" """, now)
    print(f'{row = }')

    await conn.close()

asyncio.run(main())

输出

row = <Record timestamp=datetime.datetime(2024, 9, 30, 6, 13, 8, 145093, tzinfo=datetime.timezone.utc)>
© www.soinside.com 2019 - 2024. All rights reserved.