【发布时间】:2020-01-14 10:14:44
【问题描述】:
上下文
我想在 python3 函数中的 psycopg2 查询中传递表名和查询参数。
如果我理解正确,我不应该在执行查询之前使用 python .format() 方法格式化查询字符串,而是让psycopg2 这样做。
问题
我无法成功地将表名和参数作为参数传递给我的查询字符串。
代码示例
这是一个代码示例:
import psycopg2
from psycopg2 import sql
connection_string = "host={} port={} dbname={} user={} password={}".format(*PARAMS.values())
conn = psycopg2.connect(connection_string)
curs = conn.cursor()
table = 'my_customers'
cities = ["Paris", "London", "Madrid"]
data = (table, tuple(customers))
query = sql.SQL("SELECT * FROM {} WHERE city = ANY (%s);")
curs.execute(query, data)
rows = cursLocal.fetchall()
错误
但我收到以下错误消息:
TypeError: not all arguments converted during string formatting
我还尝试将data 定义替换为:
data = (sql.Identifier(table), tuple(object_types))
但随后会弹出此错误:
ProgrammingError: can't adapt type 'Identifier'
如果我在查询字符串中输入ANY {} 而不是ANY (%s),则在前两种情况下都会显示此错误:
SyntaxError: syntax error at or near "{"
LINE 1: ...* FROM {} WHERE c...
^
最初,我没有使用 sql 模块,而是尝试将 data 作为第二个参数传递给 curs.execute() 方法,但随后表名在命令中被单引号引起来,这造成了麻烦。所以我尝试了sql 模块,认为这不是一个过时的习惯。
如果可能的话,我想保留花括号 {} 而不是 %s 来替换参数,除非这是一个坏主意。
环境
Ubuntu 18.04 64 位 5.0.0-37-generic x86_64 GNU/Linux
Python 3.6.9(默认,2019 年 11 月 7 日,10:44:02)
psycopg2.__version__
'2.8.4 (dt dec pq3 ext lo64)'
【问题讨论】:
-
表名不能为参数。您必须将其按字面意思插入到查询文本中(用变量值替换占位符)或使用动态 SQL。
-
@Akina 我认为您的评论可能是一个答案
-
@PhungDuyPhong 如果我可以添加一些代码,我可以写一个答案。但是我对 Python 一无所知...如果可以的话,添加它 - 我不介意。
-
是否有一些原因不将表名作为查询字符串的一部分传递?一个简单的字符串构造就可以了,即使它不太“安全”。我需要传递 N 个不同的表作为我的函数的参数,所以,我真的不想为此重复 N 次我的函数。
-
您可以使用
psycopg2.sql生成查询,您可能想看看这个答案stackoverflow.com/questions/58172051/…
标签: sql python-3.x psycopg2