使用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对象,再拼接起来:
- 先把字典里的每个列名转成带表前缀的
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 ]
- 用逗号加空格把这些列对象拼接起来:
column_identifier = sql.SQL(", ").join(col_identifiers)
- 再传入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
相关产品推荐
相关产品推荐

