2012-12-23 12 views
24

Ho un elenco di elenchi, ad esempio [['a','b'],['c','d']].Come utilizzare python mysqldb per inserire più righe contemporaneamente

Ho un tavolo chiamato T e due campi F1, F2. Il primo elemento nell'elenco dei campi viene mappato a F1, il secondo a F2.

Come posso inserire righe per ogni elenco interno in un singolo comando o chiamata, piuttosto che utilizzare un ciclo for come questo?

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

risposta

42

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

Quindi nel tuo caso:

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

È più efficiente dell'utilizzo di mySQL con una manipolazione di stringhe? In modo che la tua stringa è "inserire in T (F1, F2) valori (a, b), (c, d)" e passarlo per eseguire? – Jochen

+2

@Jochen Davvero non vuoi farlo se non sei assolutamente sicuro_ i tuoi dati provengono da una fonte attendibile (e continuo a credere che "non fidarti mai del cliente" è una buona regola da tenere in ogni circostanza). In genere è molto meglio, almeno quando si lavora con una libreria matura come MySQLdb, per lasciare la citazione/codifica/escaping necessaria alla lib piuttosto che tentare da soli; anche se subisce un po 'di sovraccarico, ne vale la pena. – kungphu

+0

Sfortunatamente, questo non funziona con il set di caratteri utf8mb4. Viene generato uno strano errore "codifica sconosciuta: utf8mb4" –

11

E 'possibile inserire tutte le righe in una singola istruzione come @adamhajari, ed evitare di iniezioni SQL come @zenpoy , allo stesso tempo. Hai solo bisogno di creare una dichiarazione di inserimento grande e lasciare che il formato execute di mysqldb esegua la formattazione.

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) 

Non super leggibile, ma può essere un po 'più veloce di executemany (ho provato inserendo lotti di 50000 righe in un DB locale executemany è stato più lento del 20%).

Problemi correlati