2012-10-11 24 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'} 

你能不能給我們更多的信息?