使用psycopg2/Python DB-API和PostgreSQL的参数化查询
使psycopg2将参数化查询传递给PostgreSQL的最佳方式是什么?我不想编写自己的escpaing机制或适配器,并且psycopg2源代码和示例很难在Web浏览器中阅读。使用psycopg2/Python DB-API和PostgreSQL的参数化查询
如果我需要切换到像PyGreSQL或另一个python pg适配器,这对我来说没问题。我只是想简单的参数化。
psycopg2
遵循DB-API 2.0的规则(设置在PEP-249中)。这意味着你可以从你的cursor
对象中调用execute
方法,并使用pyformat
绑定样式,它会为你逃脱。例如,下面的应该是安全的(工作):
cursor.execute("SELECT * FROM student WHERE last_name = %(lname)s",
{"lname": "Robert'); DROP TABLE students;--"})
哈哈,我刚刚得到了......小鲍比桌子! http://xkcd.com/327/ – adam 2010-07-13 14:25:08
所以上面的代码。丢下桌子还是不? – mascot6699 2016-03-26 19:40:07
@ mascot6699它没有,因为查询是参数化的。 – 2017-06-02 18:58:05
这里有几个例子,你可能会发现有用
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注入的影响。
那么除非你知道你在做什么,你应该只是concat输入到SQL查询中,因为它是一个SQL注入。 – 2013-01-25 18:45:40
downvoted由于建议,让你打开SQL注入 – 2014-12-23 05:04:57
@RandySyring这只对SQL注入开放,如果密钥没有很好定义和正确的标识符。值仍然正确参数化。 – cpburnz 2015-04-07 14:17:33
从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
什么样的你想要参数化吗?伪代码样本将很有用。 – whatnick 2009-09-23 15:53:58
Sidenote,你可能想看看SQLAlchemy,在某些方面入门的成本可能会稍微高一些,但它确实是一个非常好的ORM。 – 2009-11-09 18:55:38
为了将来的参考,答案在文档的第一页:http://initd.org/psycopg/docs/usage.html – piro 2011-05-16 16:07:16