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

使用psycopg2格式化含字典对象的SQL调用遇格式错误求助

问题:psycopg2格式化外部SQL文件时的标识符拼接错误

我在Python工作流里频繁调用存储在独立文件中的SQL,用psycopg2的标识符做格式化。但用字典修改调用时,SQL语句总是格式化错误。

SQL文件头部示例:

with my_table as (
  SELECT DISTINCT ON ("column_A")
    left_table."column_b",
    left_table."column_c",
    {column_identifier}
    ...
)

Python脚本里的代码:

col_info = my_dictionary.entry
column_identifier = " ".join([f'left_table."{x}",' for x in col_info])

sql_call = py2.sql.SQL(sql).format(
  column_identifier=py2.sql.Identifier(column_identifier),
  ...
)

执行后解析出的列变成了:

"left_table.""column_d"", "

试过用Literal替代Identifier,SQL能执行但输出无意义;又不能用AsIs,因为还有其他Identifier调用。不想把长SQL嵌入Python用f-string,求简便的格式化方案。

解决方案

问题出在你把拼接好的整串列字符串传给了Identifier——Identifier的作用是把单个标识符(比如列名、表名)转义成安全的SQL标识符,你传了带引号和逗号的整串,它自然会把整个内容当成一个标识符来转义,导致多余的引号。

正确的做法是把每个列单独处理成SQL对象,再拼接起来:

  1. 先把字典里的每个列名转成带表前缀的Identifier组合:
from psycopg2 import sql

col_info = my_dictionary.entry
# 对每个列,生成 left_table."column_x" 这样的SQL对象
col_identifiers = [
    sql.SQL("{}.{}").format(
        sql.Identifier("left_table"),
        sql.Identifier(x)
    )
    for x in col_info
]
  1. 用逗号加空格把这些列对象拼接起来:
column_identifier = sql.SQL(", ").join(col_identifiers)
  1. 再传入SQL格式化:
sql_call = sql.SQL(sql).format(
    column_identifier=column_identifier,
    # 其他需要格式化的参数
)

这样处理后,psycopg2会正确转义每个标识符,拼接出来的SQL就是合法的:

left_table."column_d", left_table."column_e"

另外,SQL文件里的占位符{column_identifier}不需要做额外修改,保持原样即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:12:46