2012-10-11 25 views
6

我想通过查询参数cursor.execute()方法MySQLdb作为命名字典,因此它们是从SQL注入转义Python MySQLdb:查询参数作为命名字典

你能解释为什么这给KeyError异常:

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

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规范*

回答

6

文档中的线以下您粘贴可能会回答你的问题是什么:

Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.

+0

我插入***列值***。文档中的一行代表以下代码是非法的: 'c.execute('从%s选择ID,其中用户名=%s',('users','bob'))' – mercador

+1

@mercador对, '从%s'片断是因为您尝试参数化表名称而导致失败的原因。以这种方式使用'execute'的好处是它有助于防止SQL注入,但是如果您采取适当的安全预防措施(我不是专家,但会涉及适当的消毒/转义参数),您可以使用Python内置的字符串格式来构建查询,然后将其传递给'execute'。同样,SQL注入是主要关心的问题。希望这可以帮助! – RocketDonkey

5

MySQLdb的允许类型的字典的查询参数。 This response显示了所有不同的方式来做到这一点。你只需要提供一个作为这样的参数(元组,字典......)作为“执行”的第二个参数的secuence。请勿将查询格式设置为“执行”方法的唯一参数,否则您可能会受到SQL注入攻击。请参阅:

user = "peter;DROP TABLE users" :_(

固定的另一种方式,因为它可以让MySQLdb的库来处理必要的检查:

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

如果想到会发生什么。

我不知道什么是错的,因为你的查询我工作得很好:

# 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'} 

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