61

使 psycopg2 将参数化查询传递给 PostgreSQL 的最佳方法是什么?我不想编写自己的转义机制或适配器,并且 psycopg2 源代码和示例很难在 Web 浏览器中阅读。

如果我需要切换到 PyGreSQL 或其他 python pg 适配器之类的东西,那对我来说很好。我只想要简单的参数化。

4

3 回答 3

120

psycopg2遵循 DB-API 2.0 的规则(在PEP-249中设置)。这意味着您可以execute从对象调用方法cursor并使用pyformat绑定样式,它会为您进行转义。例如,以下内容应该是安全的(并且可以工作):

cursor.execute("SELECT * FROM student WHERE last_name = %(lname)s", 
               {"lname": "Robert'); DROP TABLE students;--"})
于 2009-09-24T11:47:49.357 回答
34

来自 psycopg 文档

( http://initd.org/psycopg/docs/usage.html )

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

在 SQL 命令中传递变量的正确方法是使用 execute() 方法的第二个参数:

SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes

data = ("O'Reilly", )

cur.execute(SQL, data) # Note: no % operator

于 2015-09-23T15:11:13.990 回答
4

以下是一些您可能会觉得有帮助的示例

cursor.execute('SELECT * from table where id = %(some_id)d', {'some_id': 1234})

或者您可以根据字段名称、值的字典动态构建查询:

fields = ', '.join(my_dict.keys())
values = ', '.join(['%%(%s)s' % x for x in my_dict])
query = 'INSERT INTO some_table (%s) VALUES (%s)' % (fields, values)
cursor.execute(query, my_dict)

注意:这些字段必须在你的代码中定义,而不是用户输入,否则你将容易受到 SQL 注入的影响。

于 2009-09-23T18:59:40.533 回答