Python + MySQLdb executemany
-
13-09-2019 - |
Domanda
Sto usando Python e il suo modulo MySQLdb per importare alcuni dati di misura in un database Mysql. La quantità di dati che abbiamo è abbastanza elevato (attualmente circa ~ 250 MB di file CSV e un sacco di altri a venire).
Attualmente io uso cursor.execute (...) per importare alcuni metadati. Questo non è problematico, in quanto ci sono solo un paio di voci per questi.
Il problema è che quando cerco di usare cursor.executemany () per importare grandi quantità di dati di misurazione effettiva, MySQLdb solleva un
TypeError: not all arguments converted during string formatting
Il mio codice corrente è
def __insert_values(self, values):
cursor = self.connection.cursor()
cursor.executemany("""
insert into values (ensg, value, sampleid)
values (%s, %s, %s)""", values)
cursor.close()
dove values
è una lista di tuple contenenti tre stringhe ciascuno. Tutte le idee che potrebbero essere di sbagliato in questo?
Modifica
I valori sono generati da
yield (prefix + row['id'], row['value'], sample_id)
e quindi leggere in un elenco di mille in un momento in cui fila è e iteratore provenienti da csv.DictReader
.
Soluzione
In retrospettiva questo era un veramente stupido, ma difficile da errore posto. Valori è una parola chiave in SQL in modo che i valori del nome tabella deve citazioni intorno ad esso.
def __insert_values(self, values):
cursor = self.connection.cursor()
cursor.executemany("""
insert into `values` (ensg, value, sampleid)
values (%s, %s, %s)""", values)
cursor.close()
Altri suggerimenti
Il messaggio che si ottiene indica che all'interno del metodo executemany()
, una delle conversioni fallito. Controlla la tua lista values
per una tupla più di 3.
Per una verifica rapida:
max(map(len, values))
Se il risultato è superiore a 3, individuare il male tupla con un filtro:
[t for t in values if len(t) != 3]
o, se è necessario l'indice:
[(i,t) for i,t in enumerate(values) if len(t) != 3]