我有一个要从数据库中获取的行ID。我正在使用python和psycopg2,我的问题是如何有效地将这些ID传递给SQL?我的意思是,如果我知道该列表的长度,这很容易,因为我总是可以根据需要手动或自动将多个“%s”表达式添加到查询字符串中,但在这里我不知道我需要多少它们。重要的是我需要使用sql“id IN(id1,id2,...)”语句选择行。我知道可以检查列表的长度并将合适数量的“%s”连接到查询字符串中,但我担心它会非常缓慢和丑陋。有没有人知道如何解决它?请不要问为什么我需要用“IN”语句来做 - 这是一个基准测试,是我课堂作业的一部分。提前谢谢!
答案 0 :(得分:61)
Python元组转换为psycopg2中的sql列表:
cur.mogrify("SELECT * FROM table WHERE column IN %s;", ((1,2,3),))
会输出
'SELECT * FROM table WHERE column IN (1,2,3);'
对于Python新手:不幸的是,在这里使用元组而不是列表很重要。这是第二个例子:
cur.mogrify("SELECT * FROM table WHERE column IN %s;",
tuple([row[0] for row in rows]))
答案 1 :(得分:6)
现在psycopg2(https://www.psycopg.org/docs/sql.html)的sql模块可用于防止错误和注入,例如:
import psycopg2
from psycopg2 import sql
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
ids = ['a','b','c']
sql_query = sql.SQL('SELECT * FROM {} WHERE id IN ({});').format(
sql.Identifier('table_name'),
sql.SQL(',').join(map(sql.Identifier, ids))
)
print (sql_query.as_string(cur)) # for debug
cur.execute(sql_query)
from configparser import ConfigParser
def config(filename='database.ini', section='postgresql'):
# create a parser
parser = ConfigParser()
# read config file
parser.read(filename)
# get section, default to postgresql
db = {}
if parser.has_section(section):
params = parser.items(section)
for param in params:
db[param[0]] = param[1]
else:
raise Exception('Section {0} not found in the {1} file'.format(section, filename))
return db
注意:sql.Identifier
将在需要时添加引号,因此如果您也在PostgreSQL中使用带引号的标识符(必须使用它们以允许区分大小写的命名)也可以使用。
database.ini的示例和结构:
[postgresql]
host=localhost
port=5432
database=postgres
user=user
password=mypass
答案 2 :(得分:2)
这个问题很旧,也许还有一个新的问题,但是我的同事现在正在回答的问题是:
sql = "SELECT * FROM table WHERE column = ANY(%(parameter_array)s)"
cur.execute(sql,{"parameter_array": [1, 2, 3]})