Hai ragione che .import
è la strada da percorrere, ma è un comando dalla shell SQLite3.exe. Molte delle migliori risposte a questa domanda riguardano loop nativi di Python, ma se i tuoi file sono di grandi dimensioni (i miei sono da 10 ^ 6 a 10 ^ 7 record), vuoi evitare di leggere tutto nei panda o usare un ciclo di comprensione / ciclo nativo di python list (anche se non li ho presi tempo per il confronto).
Per file di grandi dimensioni, credo che l'opzione migliore sia creare la tabella vuota in anticipo utilizzando sqlite3.execute("CREATE TABLE...")
, rimuovere le intestazioni dai file CSV e quindi utilizzare subprocess.run()
per eseguire l'istruzione import di sqlite. Poiché l'ultima parte credo sia la più pertinente, inizierò con quella.
subprocess.run()
from pathlib import Path
db_name = Path('my.db').resolve()
csv_file = Path('file.csv').resolve()
result = subprocess.run(['sqlite3',
str(db_name),
'-cmd',
'.mode csv',
'.import '+str(csv_file).replace('\\','\\\\')
+' <table_name>'],
capture_output=True)
Spiegazione
Dalla riga di comando, il comando che stai cercando è sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
esegue un processo da riga di comando. L'argomento a subprocess.run()
è una sequenza di stringhe che vengono interpretate come un comando seguito da tutti i suoi argomenti.
sqlite3 my.db
apre il database
-cmd
flag dopo il database consente di passare più comandi follow-on al programma sqlite. Nella shell, ogni comando deve essere racchiuso tra virgolette, ma qui devono essere solo il proprio elemento della sequenza
'.mode csv'
fa quello che ti aspetteresti
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
è il comando di importazione.
Sfortunatamente, poiché il sottoprocesso passa tutti i follow-on -cmd
come stringhe tra virgolette, è necessario raddoppiare le barre rovesciate se si dispone di un percorso di directory di Windows.
Eliminazione delle intestazioni
Non proprio il punto principale della domanda, ma ecco cosa ho usato. Di nuovo, non volevo leggere tutti i file in memoria in nessun momento:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)