首页 > 解决方案 > psycopg2 的 sql.Identifier 抛出“没有函数匹配...”错误

问题描述

sql.SQL() 可以正常工作,但是我遇到了 sql.Identifier 和 sql.Literal 的问题。两者都抛出这样的错误:

cur.execute(sql.SQL("""
psycopg2.errors.UndefinedFunction: function identifier(unknown) does not exist
LINE 3:      Identifier('table_name')
             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

这是我正在使用的代码:

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

我已尽可能按照说明进行操作,据我所知,一切都是正确的。我也从 psycopg2 导入了 sql 并建立了我的连接。如果我删除 sql.SQL 和 sql.Identifier 并将 sql 作为字符串传递以执行,它可以完美运行,但是,我希望它尽可能安全,因为其他部分可能有用户输入。我是不是做错了什么,或者有没有办法让这个工作我还没有偶然发现?

Psycopg2 也完全是最新的。

标签: pythonsqlpostgresqlpsycopg2

解决方案


您遇到错误是因为您正在格式化查询字符串而不是sql.SQL对象。

长话短说:

from psycopg2 import sql

$> sql.SQL.format
>>> <function psycopg2.sql.SQL.format(self, *args, **kwargs)>

所以,如果你直接格式化你的字符串,你最终会得到一个错误的 SQL 查询(格式不正确):

$> query = sql.SQL("""
    select {} from information_schema.tables where table_schema = 'my_schema';
    """.format(sql.Identifier('table_name')))                              
$> query.as_string(conn)                                                 
>>> "select Identifier('table_name') from information_schema.tables where table_schema = 'my_schema'; "

否则,如果您格式化sql.SQL对象:

$> query = sql.SQL("""
   select {} from information_schema.tables where table_schema = 'my_schema';
   """).format(sql.Identifier('table_name'))
$> query.as_string(conn)
>>> 'select "table_name" from information_schema.tables where table_schema = \'my_schema\';'

更多信息:sql.SQL.format(*args, **kwargs)


推荐阅读