Masz rację, .importto jest właściwy sposób, ale to polecenie z powłoki SQLite3.exe. Wiele najpopularniejszych odpowiedzi na to pytanie dotyczy natywnych pętli Pythona, ale jeśli twoje pliki są duże (moje to 10 ^ 6 do 10 ^ 7 rekordów), nie chcesz czytać wszystkiego w pandach lub używać natywnego rozumienia / pętli list Pythona (chociaż nie czas na ich porównanie).
W przypadku dużych plików uważam, że najlepszą opcją jest wcześniejsze utworzenie pustej tabeli za pomocą sqlite3.execute("CREATE TABLE..."), usunięcie nagłówków z plików CSV, a następnie użycie subprocess.run()do wykonania instrukcji importu sqlite. Ponieważ ostatnia część jest, moim zdaniem, najbardziej trafna, zacznę od tego.
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)
Wyjaśnienie
W wierszu poleceń szukane polecenie to sqlite3 my.db -cmd ".mode csv" ".import file.csv table". subprocess.run()uruchamia proces wiersza poleceń. Argument do subprocess.run()jest sekwencją ciągów, które są interpretowane jako polecenie, po którym następują wszystkie jego argumenty.
sqlite3 my.db otwiera bazę danych
-cmdFlaga po bazie danych pozwala na przekazywanie wielu poleceń do programu sqlite. W powłoce każde polecenie musi być w cudzysłowach, ale tutaj wystarczy, że będzie to ich własny element sekwencji
'.mode csv' robi to, czego można się spodziewać
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'to polecenie importu.
Niestety, ponieważ podproces przekazuje wszystkie następstwa -cmdjako łańcuchy cytowane w cudzysłowie, musisz podwoić ukośniki odwrotne, jeśli masz ścieżkę do katalogu systemu Windows.
Usuwanie nagłówków
Właściwie nie jest to główny punkt pytania, ale oto, czego użyłem. Ponownie, w żadnym momencie nie chciałem wczytywać całych plików do pamięci:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)