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

如何使用pg8000.connect向PostgreSQL存储过程传递嵌套数组

解决pg8000传递PostgreSQL嵌套自定义类型数组的问题

错误原因

你手动将嵌套数组转换为字符串并通过参数传递,导致PostgreSQL无法正确解析数组字面量:

  • 手动拼接的字符串格式不符合PostgreSQL复合类型数组的语法要求
  • pg8000的参数绑定会自动处理字符串转义,你手动添加的转义符会失效,导致格式混乱
  • 错误提示中的"[" must introduce explicitly-specified array dimensions说明PostgreSQL无法识别你构造的数组格式

解决方案

不要手动拼接字符串,直接用Python的嵌套元组/列表结构对应PostgreSQL的自定义类型及数组,让pg8000自动完成类型映射。

正确代码示例

import pg8000

sql = """CALL insert_family(
    %s,
    %s::parent_type[]
);"""

with pg8000.connect(host="localhost", database="mydb", user="myuser", password="mypass") as con:
    with con.cursor() as cursor:
        # 用Python嵌套结构对应PostgreSQL的类型:
        # - 外层列表对应 parent_type[] 数组
        # - 每个父元素是元组,对应 parent_type 复合类型(p字段, children数组)
        # - children数组是子元组的列表,对应 child_type[] 数组
        parents_data = [
            ("Zeus", [(1, "Hestia"), (2, "Hades")])
        ]
        cursor.execute(sql, args=('Cronus', parents_data))

原理说明

pg8000会自动将Python的:

  • 列表转换为PostgreSQL的数组
  • 元组转换为PostgreSQL的复合类型(row type)

这样就避免了手动构造字符串的格式错误,同时也更安全(防止SQL注入)。

备选方案:显式构造数组字面量(不推荐)

如果必须手动构造字符串,需要严格遵循PostgreSQL的数组字面量语法,注意转义和格式:

import pg8000

sql = """CALL insert_family(
    %s,
    %s::parent_type[]
);"""

with pg8000.connect(host="localhost", database="mydb", user="myuser", password="mypass") as con:
    with con.cursor() as cursor:
        # 严格按照PostgreSQL复合类型数组的格式构造字符串
        parent_str = """("Zeus", '{"(1,Hestia)","(2,Hades)"}'::child_type[])"""
        cursor.execute(sql, args=('Cronus', [parent_str]))

注意:这种方式容易出错,且存在SQL注入风险,仅在特殊场景下使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:15:42