2012-12-23 58 views
24

我有一個列表列表,例如[['a','b'],['c','d']]如何使用python mysqldb一次插入多行

我有一個表T和兩個字段F1,F2。字段列表中的第一項映射到F1,第二項到F2

如何在單個命令或調用中爲每個內部列表插入行,而不是像這樣使用for循環?

for i in [['a','b'],['c','d']]: 
    c.execute("insert into T (F1,F2) values (%s, %s)", (i[0], i[1])) 

回答

42

MySQLdb User's Guide

c.executemany(
     """INSERT INTO breakfast (name, spam, eggs, sausage, price) 
     VALUES (%s, %s, %s, %s, %s)""", 
     [ 
     ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95), 
     ("Not So Much Spam Plate", 3, 2, 0, 3.95), 
     ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95) 
     ]) 

所以你的情況:

c.executemany("insert into T (F1,F2) values (%s, %s)", 
    [('a','b'),('c','d')]) 
+2

這比用一些字符串操作使用mySQL構建更高效嗎?因此,你的字符串是「插入到T(F1,F2)值(a,b),(c,d)」並傳遞給它執行? – Jochen

+2

@Jochen除非您絕對確信您的數據來自可信來源(並且我仍然相信「永遠不要相信客戶端」是保持所有情況的良好規則),否則您確實不想這樣做。通常情況會好很多,至少當你使用像MySQLdb這樣的成熟庫時,必須將引用/編碼/轉義保留在lib中而不是自己嘗試;即使它會帶來一點開銷,但心靈的安寧是值得的。 – kungphu

+0

不幸的是,這不適用於utf8mb4字符集。它會拋出一個奇怪的錯誤「未知的編碼:utf8mb4」 –

11

它可以插入像@adamhajari一個單獨的語句中的所有行,並避免SQL注入像@zenpoy , 與此同時。你只需要創建一個大插入語句,並讓mysqldb的execute進行格式化。

values_to_insert = [('a','b'),('c','d')] 
query = "INSERT INTO T (F1, F2) VALUES " + ",".join("(%s, %s)" for _ in values_to_insert) 
flattened_values = [item for sublist in values_to_insert for item in sublist] 
c.execute(query, flattened_values) 

不是超級可讀的,但也可以是比executemany稍快(我想在本地DB插入50000行批次,executemany較慢20%)。