Python MySQLdb:将参数作为命名字典查询

mer*_*dor 7 python mysql-python

我想通过查询参数cursor.execute()的方法MySQLdb为命名的字典,使得它们逃脱从SQL注入.

你能解释一下为什么会这样KeyError:

>>> c.execute('select id from users where username=%(user)s', {'user':'bob',})
KeyError: 'user'
Run Code Online (Sandbox Code Playgroud)

MySQLdb手册http://mysql-python.sourceforge.net/MySQLdb.html说:

paramstyle

字符串常量,说明接口所需的参数标记格式的类型.设置为'format'= ANSI C printf格式代码,例如'...WHERE name=%s'.如果使用映射对象conn.execute(),则接口实际上使用'pyformat'= Python扩展格式代码,例如'...WHERE name=%(name)s'.但是,API目前不允许在paramstyle中指定多个样式.

Alb*_*gía 8

MySQLdb允许dicts作为查询参数.此响应显示了所有不同的方法.您只需提供一个secuence作为参数(元组,字典......)作为"执行"的第二个参数.请勿将查询格式化为"执行"方法的一个参数,否则您可能会遇到SQL注入攻击.看到:

"SELECT * FROM users WHERE username = '%s'" % (user)
Run Code Online (Sandbox Code Playgroud)

想想如果会发生什么:

user = "peter;DROP TABLE users"   :_(
Run Code Online (Sandbox Code Playgroud)

另一种方式是安全的,因为它允许MySQLdb库处理必要的检查.

我不知道有什么问题,因为你的查询对我来说很好:

# Connect to db
# Open a cursor
stmt = "SELECT * FROM users WHERE username = %(user)s"
cursor.execute(stmt, {"user": "bob"})
user = cursor.fetchone()
print user

{'username': 'bob', 'alias': 'bobby', 'avatar': 'default', 'fullname': 'bob'}
Run Code Online (Sandbox Code Playgroud)

你能告诉我们更多信息吗?


Roc*_*key 3

文档中您粘贴的内容后面的行可能会回答您的问题:

参数占位符只能用于插入列值。它们不能用于 SQL 的其他部分,例如表名、语句等。

  • 然而问题中的代码**不使用 SQL 参数作为值之外的任何东西**。 (4认同)
  • 我正在插入一个***列值***。文档中的行意味着以下代码是非法的: `c.execute('select id from %s where username=%s', ('users', 'bob'))` (3认同)
  • @mercador是的,“from %s”部分是导致失败的原因,因为您正在尝试参数化表名。以这种方式使用“execute”的好处是它有助于防止 SQL 注入,但是如果您采取适当的安全预防措施(我不是这方面的专家,但会涉及对参数进行适当的清理/转义),您可以使用 Python 内置的字符串格式来构建查询,然后将其传递给“execute”。同样,SQL 注入是主要问题。希望这可以帮助! (2认同)