【问题标题】:Parameterized queries with psycopg2 / Python DB-API and PostgreSQL使用 psycopg2 / Python DB-API 和 PostgreSQL 的参数化查询
【发布时间】:2010-11-30 19:19:47
【问题描述】:

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

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

【问题讨论】:

  • 你想要什么样的参数化?伪代码示例会很有用。
  • 旁注,你可能想研究一下 SQLAlchemy,在某些方面入门成本可能会高一些,但它确实是一个非常好的 ORM。
  • 供以后参考,答案在文档的第一页:initd.org/psycopg/docs/usage.html
  • 在文档中,示例非常简单。没有显示如何对动态值进行更复杂的查询(如更新)。比如:set height=5, weight=70
  • 如果您提出要解决的特定问题,Stack Overflow 会变得更加有用。例如查询与更新表等。因此,这里的答案非常笼统,尽管标题让我进入,但无助于解决我遇到的问题。

标签: python postgresql psycopg2


【解决方案1】:

这里有一些你可能会觉得有用的例子

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注入。

【讨论】:

  • 好吧,除非你知道你在做什么,否则你不应该将输入连接到 sql 查询中,因为它是 SQL 注入。
  • 由于建议您对 SQL 注入持开放态度而被否决
  • @RandySyring 只有在没有很好地定义键和正确的标识符时才对 SQL 注入开放。这些值仍然正确参数化。
  • 也就是说,在一般情况下,它会让你对 SQL 注入持开放态度。
  • 您的第一个示例不起作用。来自文档:The variables placeholder must always be a %s, even if a different placeholder (such as a %d for integers or %f for floats) may look more appropriate。你使用了%d
【解决方案2】:

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;--"})

【讨论】:

  • @mascot6699 它没有,因为查询是参数化的。
  • 好消息是,由于该表名为“student”,而不是“students”;即使代码不安全,它也会失败。给你黑帽的教训:测试你的漏洞!
【解决方案3】:

来自 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

【讨论】:

    猜你喜欢
    • 2021-08-09
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多