You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

asyncpg传入int参数触发DataError:期望str却得到int,原因是什么?

asyncpg传入整数参数报错的原因及解决办法

问题描述

我承认不太理解asyncpg的编解码器工作机制,但其表现似乎与我的预期相悖:

import asyncio
import asyncpg


async def main():
    conn = await asyncpg.connect('postgresql://postgres@localhost/test')

    print(await conn.fetchval("select $1", 'a'))  # 正常运行:输出'a'
    print(await conn.fetchval("select $1", 1))  # 报错:invalid input for query argument $1: 1 (expected str, got int)

asyncio.run(main())

看起来asyncpg要求参数必须是字符串,但我想传入整数,为何会执行失败?

原因分析

这个报错并非因为asyncpg只接受字符串参数,核心原因是你大概率给当前连接注册了自定义的字符串编解码器,覆盖了默认的基础类型处理逻辑。

默认状态下,asyncpg会自动适配整数、字符串等PostgreSQL基础类型的编码/解码,不会出现这类类型不匹配的报错。如果出现这个问题,你可以检查代码中是否有类似如下的自定义编解码器注册操作:

await conn.set_type_codec(
    'text',
    encoder=str,
    decoder=str,
    schema='pg_catalog'
)

当你注册了针对pg_catalog.text类型的自定义编解码器后,PostgreSQL执行select $1时会默认将参数推断为text类型,此时asyncpg会按照你指定的编解码器要求参数必须是字符串类型,传入整数就会触发类型检查报错。

解决办法

  • 恢复默认编解码器:如果不需要自定义的文本类型编解码逻辑,直接移除set_type_codec相关的调用,asyncpg就会回到默认的类型处理模式,自动识别并处理整数参数。
  • 显式指定参数类型:如果必须保留自定义编解码器,在查询时显式声明参数的PostgreSQL类型,让asyncpg使用对应类型的编解码器处理:
    print(await conn.fetchval("select $1::int", 1))
    
  • 针对自定义类型注册编解码器:避免覆盖pg_catalog下的系统默认类型编解码器,只针对你自己定义的数据库类型注册编解码逻辑。

内容的提问来源于stack exchange,提问作者DMac the Destroyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 12:25:04