2012-02-07 70 views
4

我注意到大多數的消息來源說,以最佳實踐來執行SQL語句在Python是這樣的:使用MySQLdb在Python中執行像這樣的SQL查詢是否安全?

cursor.execute('select * from coworkers where name = :1 and clue > :2', [ name, clue_threshold ]) 

其他消息來源說

cursor.execute("select * from coworkers where name = %s and clue > %s", (name, clue_threshold)) 

我認爲這是非常相似的。

無論如何,我一直在做的是創建一個字典和存儲值。例如,初始字典biz_info看起來是這樣的:

biz_info = { 
    'business'  : None, 
    'name'   : None, 
    'neighborhood' : None, 
    'address'  : None, 
    'city'   : None, 
    'state'  : None, 
    'zip_code'  : None, 
    'latitude'  : None, 
    'longitude' : None, 
    'phone'  : None, 
    'url'   : None, 
    'yelp_url'  : None, 
} 

然後我執行SQL語句這樣

execute_sql(cur, "insert into " + TABLE_BIZ_NAME + """ values (
        NULL, 
        %(name)s, 
        %(neighborhood)s, 
        %(address)s, 
        %(city)s, 
        %(state)s, 
        %(zip_code)s, 
        %(latitude)s, 
        %(longitude)s, 
        %(phone)s, 
        %(url)s, 
        %(yelp_url)s, 
        NULL 
        )""" 
        , biz_info) 

這是對SQL注入安全嗎?我想使用字典來存儲信息,因爲它更容易管理。

說實話,我並不甚至完全知道什麼兩者的區別:一個%,%s%d%()s意味着參數化查詢。基本上我所知道的是使用

cursor.execute("select * from coworkers where name = '%s' and clue > %d" % (name, clue_threshold)) 
+0

「這對sql注入安全嗎?」。是。 「我甚至不完全確定在參數化查詢中使用%,,,%s,%d和%()s的意義是什麼」。這是否意味着你在問關於Python DB-API的規則?你問這個http://www.python.org/dev/peps/pep-0249/? – 2012-02-07 22:17:47

回答

3

用於將參數傳遞到SQL命令字符串的方式取決於數據庫(sqlite的,例如,使用?)上。

根據MySQLdb documentation,可以使用paramstyle參數設置格式化字符串的首選方式(formatpyformat)。

您的問題中的第一個例子似乎不被支持。無論如何,我會說只要不像上一個例子那樣格式化整個字符串,就可以保證安全,因爲可以假設查詢參數將被正確轉義。

1

您的插入語句應該明確指定要設置的字段名稱,以防止模式更改發生中斷。另外,我發現你的代碼太重複了。我會寫插入更多的東西是這樣的:

cursor.execute \ 
    (
     "insert into " 
    + 
     TABLE_BIZ_NAME 
    + 
     "(" 
    + 
     ", ".join(biz_info.keys()) 
    + 
     ") values (" 
    + 
     ", ".join(("%s",) * len(biz_info)) 
    + 
     ")", 
    biz_info.values() 
) 

這樣,字段名只需要列出一次,在創建biz_info字典的。任何未來的變化只需要在那裏更新。

+0

我喜歡你如何使用'join()'和'keys()'。謝謝你的提示! – hobbes3 2012-02-08 17:08:20

相關問題