2012-12-05 74 views
0

當我想要做IN查詢與MySQLdb,我喜歡寫東西更好的辦法做到`IN`查詢與Python MySQLdb的

ids = [1,2,3,4,5] # in most cases, this is passed in as a parameter 
placeholder = ",".join(["%s"] % len(ids)) 
cursor.execute("SELECT * FROM a_table WHERE id IN (%s)" % placeholders, 
       ids) 

這是非常麻煩無處不在重複這一點。

我已閱讀MySQLdb的使用說明書,但未發現任何相關內容。

所以我想知道其他人怎麼做到這一點? MySQLdb是否提供了一個沒有記錄的更好的方法?

+0

爲什麼你有'LEN(IDS)'?它不應該是'placeholder =「,」。join(ids)'? –

+0

@YevgenYampolskiy我用它在第二行創建了一個字符串,如「%s,%s,%s」。後來,我將這個字符串插入到'sql'語句中,並將列表'ids'作爲第二個參數。 – satoru

回答

0

如果你願意嘗試SQLAlchemy(我更熟悉的燒瓶SQLAlchemy的,所以你可能需要稍微修改代碼),可以簡化本查詢到的東西:

class a_table(db.Model): 
    __tablename__ = 'a_table' 
    __table_args__ = { 
     'autoload': True, 
     'autoload_with': db.engine 
    } 

ids = [1,2,3,4,5] 
results = a_table.query.filter(a_table.id.in_(ids)).all() 
0

上面的方法似乎是最好的方法,因爲如您所知,參數化值將轉換爲文字。如果您多次進行此操作,我唯一(無可否認的)建議就是在轉換過程中完成一項功能。並不理想,但很少繞過MySQLdb提供的內置消毒功能,我似乎無法找到另一種方法來處理它(但並不是說沒有其他方法)。另外,你可能已經想到了這一點已經:)

def InQuery(query, vals): 
    # Would likely have to be adjusted to handle more complex/compound cases 
    return query % ', '.join(['%s'] * len(vals)) 

然後執行類似的疑問:

ids = [1,2,3,4,5] 
cursor.execute(InQuery(query, ids), ids) 
+0

我認爲用這種方式格式化'SQL'語句可能有被SQL注入攻擊的風險。 – satoru

+0

@ Satori.Logic在第一個例子中,是的:)第二個例子(使用實際的查詢結構)利用了MySQLdb內置的參數清理(我現在無法測試:)。 – RocketDonkey

+0

@ Satoru.Logic對不起,我確切地看到你現在在說什麼(道歉 - 應該等到我真的可以先審覈這件事)。我會修補一下,但如果找不到任何可行的話,我會刪除它。 – RocketDonkey