11

我想将查询参数作为命名字典传递给cursor.execute()方法,以便它们从 SQL 注入中逃脱。MySQLdb

你能解释为什么这会给出KeyError

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

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

参数样式

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

4

2 回答 2

15

MySQLdb允许字典作为查询参数。此响应显示了所有不同的方法。您只需要提供一个序列作为这样的参数(元组,字典......)作为“执行”的第二个参数。不要将您的查询格式化为“执行”方法的一个参数,否则您可能会受到 SQL 注入攻击。看:

"SELECT * FROM users WHERE username = '%s'" % (user)

想想如果user等于一个字符串会发生什么:

peter';DROP TABLE users;SELECT * from users where ''='

另一种方式是安全的,因为它允许 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'}

你能给我们更多的信息吗?

于 2013-05-29T15:02:18.943 回答
3

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

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

于 2012-10-11T03:00:00.730 回答