2012-12-23 24 views
24

Mam listę list, np. [['a','b'],['c','d']].Jak używać Pythona mysqldb do wstawiania wielu wierszy jednocześnie?

Mam tabelę o nazwie T i dwa pola F1, F2. Pierwszy element na liście pól jest mapowany na F1, drugi pod F2.

Jak mogę wstawić wiersze dla każdej listy wewnętrznej za pomocą pojedynczego polecenia lub wywołania, zamiast używać pętli for?

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

Odpowiedz

42

Od 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) 
     ]) 

więc w Twoim przypadku:

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

Czy jest to bardziej wydajne niż użycie kompilacji mySQL przy manipulowaniu ciągami znaków? Aby twój ciąg znaków był "wstawiany do wartości T (F1, F2) (a, b), (c, d)" i przekazywać go do wykonania? – Jochen

+2

@Jochen Naprawdę nie chcesz tego robić, chyba że jesteś całkowicie pewny, że twoje dane pochodzą z zaufanego źródła (i nadal uważam, że "nigdy nie ufaj klientowi" to dobra zasada, aby zachować w każdych okolicznościach). Zasadniczo jest o wiele lepiej, przynajmniej gdy pracujesz z dojrzałą biblioteką, taką jak MySQLdb, aby pozostawić konieczne cytowanie/kodowanie/ucieczkę do biblioteki, zamiast próbować samemu; nawet jeśli wiąże się to z pewnym obciążeniem, spokój jest tego wart. – kungphu

+0

Niestety, to nie działa z zestawem znaków utf8mb4. Rzuca dziwny błąd "nieznane kodowanie: utf8mb4" –

11

Jest możliwe, aby wstawić wszystkie wiersze w jednym sprawozdaniu jak @adamhajari i uniknąć SQL injection jak @zenpoy , w tym samym czasie. Trzeba tylko utworzyć dużą instrukcję wstawiania i umożliwić formatowanie w 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) 

nie bardzo odczytu, ale może być nieco szybciej niż executemany (I próbuje wkładania partii 50000 wierszy miejscowego DB executemany o 20% mniejsza).

Powiązane problemy