2010-06-28 65 views
19

我很難在python中獲得一些sql來正確地通過MySQLdb。這是pythons字符串格式,這是殺了我。帶有SQL通配符和喜歡的Python字符串格式

我的sql語句使用LIKE關鍵字和通配符。我在Python中嘗試了許多不同的東西。問題是一旦我得到其中一個工作,MySQLdb中有一行代碼以字符串格式進行打包。

嘗試1:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query)

這是一個沒有去。我得到的值錯誤:

ValueError: unsupported format character ''' (0x27) at index 128

嘗試2:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '\%%s\%'" % (query)

我從嘗試1.

嘗試3相同的結果:

like = "LIKE '%" + str(query) + "%'" totalq = "SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username " + like

這正確創建totalq變量,但現在當我去運行查詢時,我從MySQLdb中收到錯誤:

File "build/bdist.macosx-10.6-universal/egg/MySQLdb/cursors.py", line 158, in execute query = query % db.literal(args) TypeError: not enough arguments for format string

嘗試4:

like = "LIKE '\%" + str(query) + "\%'" totalq = "SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username " + like

這是企圖3.

輸出相同的這一切似乎真的很奇怪。如何在python中使用sql語句中的通配符?

+0

要echo @bernie below:From psycopg docs:http://initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters:「絕不,永遠不要使用Python字符串連接(+)或字符串參數插值(%)將變量傳遞給SQL查詢字符串。 「除了SQL注入攻擊之外,第二個好處是驅動程序」可以自動將Python對象與SQL文字進行轉換:使用此功能,您的代碼將更加健壯和可靠「。這與」天真處理查詢字符串的組成,例如使用字符串連接「 – 2013-06-10 13:21:09

回答

10

這不是字符串格式化,但問題是如何查詢應根據在Python數據庫操作要求(PEP 249

嘗試這樣執行:

sql = "SELECT column FROM table WHERE col1=%s AND col2=%s" 
params = (col1_value, col2_value) 
cursor.execute(sql, params) 

here are some examples for psycog2,你有一些解釋那也應該對mysql有效(mysqldb也遵循PEP249 dba api指導2。0:here are examples for mysqldb

+0

謝謝。 MySQL數據庫會計算出如何在sql語句中跳過參數,但是現在它可以像這樣拋出參數。 – gngrwzrd 2010-06-28 18:07:57

+0

很高興幫助你!我花了很多時間,直到我想到前一段時間:) – dzida 2010-06-28 21:12:11

6

爲了逃避Python中的字符串格式化表達式&符號,雙符號:

'%%%s%%' % search_string 

編輯:但我絕對有另一個答案一致。 SQL查詢中的直接字符串替換幾乎總是一個壞主意。

20

這些查詢似乎都容易受到SQL注入攻擊。

嘗試這樣代替:

curs.execute("""SELECT tag.userId, count(user.id) as totalRows 
        FROM user 
      INNER JOIN tag ON user.id = tag.userId 
       WHERE user.username LIKE %s""", ('%' + query + '%',)) 

如果有兩個參數傳遞給​​。

+1

這看起來也容易受到SQL注入的影響,通過任何用於連接數據庫的庫來使用參數化查詢都是最好的選擇 – jrdioko 2010-06-28 17:45:43

+4

@jrdioko:感謝您的評論請注意,沒有實際的字符串插值,並且查詢*是由'execute()'方法準備的。 – bernie 2010-06-28 17:49:31

+0

我回過頭來看,它的語法看起來就是這個庫是如何實現參數化查詢的。 – jrdioko 2010-06-28 17:51:45

-1

我有一個解決問題的方法:

不能使用:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query) 

你可以用串模板改變它,如:

import MySQLdb 
import string # string module 
....... 
value = {'user':'your value'} 
sql_template = string.Template(""" 
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN 
tag ON user.id = tag.userId WHERE user.username LIKE '%$user%' 
""") 

sql = sql_template.substitute(value) 

try: 
    cursor.execute(sql) 
    ........... 
except: 
    ........... 
finally : 
    db.close() 
+0

這不如直接替換,你不應該這樣做。佔位符如上所述,在PEP 249文檔中描述如何正確地做到這一點 – Turk 2017-04-10 20:51:31