You need to enable JavaScript to run this app. psycopg2使用sql.Identifier、sql.Literal时报identifier函数不存在错误
优惠活动
大模型
产品
解决方案
定价
更多

psycopg2使用sql.Identifier、sql.Literal时报identifier函数不存在错误

错误根因

  • 完全颠倒了psycopg2 sql模块的使用顺序,跳过了官方设计的转义逻辑:
    你的代码是先对原生Python三引号字符串调用内置.format()方法,传入sql.Identifier('table_name')对象。原生字符串格式化会把sql.Identifier对象转换为其字符串表示(即纯文本Identifier('table_name'))直接嵌入SQL模板,之后才把这段嵌入了错误文本的字符串传给sql.SQL包装执行。
  • 最终发送到数据库的SQL片段里,select后的内容是Identifier('table_name'),PostgreSQL会把这段文本识别为对identifier函数的调用,由于不存在匹配的函数定义,就会抛出你遇到的psycopg2.errors.UndefinedFunction错误。
  • sql.Identifier、sql.Literal是psycopg2 sql模块的专属拼接元素,必须交给sql.SQL实例的内置方法处理,不能提前通过普通字符串格式化转成纯文本。

你之前去掉sql.SQL和sql.Identifier直接传普通SQL字符串能正常运行,是因为不存在对象被转成错误文本的环节,数据库收到的是纯合法SQL文本。

正确实现方式

核心规则:

  • 动态SQL模板先用sql.SQL包裹,模板里的动态内容用{}做占位符
  • 调用sql.SQL实例自带的.format()方法,按占位符顺序传入对应的拼接元素:表名、字段名这类数据库标识符用sql.Identifier包裹,普通查询值用sql.Literal包裹
  • 完成占位符替换的sql.SQL实例再传给cur.execute()执行

代码示例

基础写法(替代你现在的代码)

query = sql.SQL("""
select 
  {}
from
  information_schema.tables
where
  table_schema = 'my_schema';
""").format(
    sql.Identifier('table_name')
)
cur.execute(query)

结合sql.Literal的写法(避免硬编码字符串)

query = sql.SQL("""
select 
  {}
from
  information_schema.tables
where
  table_schema = {};
""").format(
    sql.Identifier('table_name'),
    sql.Literal('my_schema')
)
cur.execute(query)

注意事项

  • 不要对sql.SQL实例使用Python原生的字符串格式化方式(f-string、%格式化、内置str.format()),必须走sql模块自带的替换逻辑,否则会失去自动转义、防SQL注入的作用。
  • 不要把sql.Identifier、sql.Literal对象和普通SQL文本直接做字符串拼接,会破坏转义规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 20:24:04