使 psycopg2 将参数化查询传递给 PostgreSQL 的最佳方法是什么?我不想编写自己的转义机制或适配器,并且 psycopg2 源代码和示例很难在 Web 浏览器中阅读。
如果我需要切换到 PyGreSQL 或其他 python pg 适配器之类的东西,那对我来说很好。我只想要简单的参数化。
使 psycopg2 将参数化查询传递给 PostgreSQL 的最佳方法是什么?我不想编写自己的转义机制或适配器,并且 psycopg2 源代码和示例很难在 Web 浏览器中阅读。
如果我需要切换到 PyGreSQL 或其他 python pg 适配器之类的东西,那对我来说很好。我只想要简单的参数化。
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;--"})
来自 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
以下是一些您可能会觉得有帮助的示例
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 注入的影响。