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

如何让asyncpg返回PostgreSQL原始数据,避免自动处理?

用asyncpg直接获取PostgreSQL返回的原始JSON字节/字符串数据

要避免asyncpg把查询结果解析成Record或字典,直接拿到PostgreSQL返回的原始JSON文本/字节,有两个靠谱的方案:

方案1:修改SQL查询,强制返回文本类型

直接在查询里把JSON结果转成text类型,asyncpg就会跳过JSON解析逻辑,直接返回字符串。把你的查询调整成:

query = "SELECT (ARRAY_AGG(JSON_STRIP_NULLS('my', 'data', 'from', (select array_agg(somewhere) from databasetable))))::text"

然后在生成器里直接取Record的第一个字段(因为cursor返回的是单字段Record):

async def my_generator():
    async with get_transaction_somehow() as conn:
        async for record in conn.cursor(query, my_data):
            yield record[0]  # 直接输出原始JSON字符串

方案2:全局设置JSON类型编解码器,跳过解析

如果不想每次修改查询,可以在asyncpg连接上自定义类型编解码器,让所有JSON/JSONB类型直接返回原始字节或字符串:

async def setup_connection(conn):
    # 设置JSON类型直接返回原始字节(要字符串的话,把lambda里的data改成data.decode())
    await conn.set_type_codec(
        'json',
        encoder=None,
        decoder=lambda data, _: data,
        format='binary'
    )
    # 同样处理jsonb类型
    await conn.set_type_codec(
        'jsonb',
        encoder=None,
        decoder=lambda data, _: data,
        format='binary'
    )

# 初始化连接池时传入这个setup函数
pool = await asyncpg.create_pool(
    dsn="your_postgres_dsn",
    init=setup_connection
)

之后原有查询不需要改动,直接从Record里取字段就能拿到原始数据:

async def my_generator():
    async with get_transaction_somehow() as conn:
        async for record in conn.cursor(query, my_data):
            yield record[0]  # 返回原始JSON字节,直接输出即可

性能优化逻辑

PostgreSQL已经输出了结构化的JSON,asyncpg默认会把它解析成Python字典,你后续又要把字典重新序列化成JSON字符串——这两步属于无意义的重复开销。数据量越大,跳过解析和二次序列化带来的CPU、内存节省越明显。

内容的提问来源于stack exchange,提问作者Automatico

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:02:43