使用 psycopg2 编写动态 SQL 字符串

Posted

技术标签:

【中文标题】使用 psycopg2 编写动态 SQL 字符串【英文标题】:Compose dynamic SQL string with psycopg2 【发布时间】:2018-03-27 23:13:53 【问题描述】:

我在 python (2.7.10) 中使用psycopg2 连接到 postgresql 数据库。文档非常清楚动态 SQL 语句的组成:

从不、从不、从不使用 Python 字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL 查询字符串。甚至在枪口下也没有。

psycopg2 2.7 版中,有新的sql 模块可以安全地防止SQL 注入来执行此字符串组合。尽管如此,我还是不明白如何正确地构造如下语句:

import psycopg2 as ps

C = psycopg.connect(host='my_host', port=Port, database='My_DB')
cur = C.cursor()
schema = 'some_schema'
table = 'some_table'
SQL = cur.execute("SELECT * FROM "+schema+"."+table+";") # This is horribly wrong
SQL = cur.execute("SELECT * FROM some_schema.some_table;") # That's what the result should be

【问题讨论】:

【参考方案1】:

您可以使用psycopg2.sql.Identifier 将标识符插入到查询中,例如:

from psycopg2.sql import Identifier, SQL

query = SQL('SELECT * FROM .').format(*map(Identifier, (schema, table)))
print(query.as_string(conn))
cur.execute(query)

根据链接的文档页面,在psycopg2 v2.8+ 中,您还可以将多个字符串传递给Identifier 以表示限定名称,即以点分隔的标识符序列:

query = SQL('SELECT * FROM ').format(Identifier(schema, table))

【讨论】:

以上是关于使用 psycopg2 编写动态 SQL 字符串的主要内容,如果未能解决你的问题,请参考以下文章

psycopg2转义字符问题

中断键时使用 psycopg2 终止未完成的 SQL 提交查询

尝试使用 psycopg2.sql 在 python 中创建 Redshift 表

python3 psycopg SQL 标识符必须是字符串

如何显式引用字符串值(Python DB API/Psycopg2)

Psycopg2 SQL 语句在查询生成器中工作,但不是在 Python 中