Haklısın .import
, gitmenin yolu bu, ama bu SQLite3.exe kabuğundan bir komut. Bu sorunun en iyi yanıtlarının çoğu yerel python döngülerini içerir, ancak dosyalarınız büyükse (benimki 10 ^ 6 ila 10 ^ 7 kayıtsa), her şeyi pandalarda okumaktan veya yerel bir python listesi anlama / döngüsü kullanmaktan kaçınmak istersiniz. (karşılaştırma için zamanlamamama rağmen).
Büyük dosyalar için, en iyi seçeneğin boş tabloyu kullanarak önceden oluşturmak, sqlite3.execute("CREATE TABLE...")
CSV dosyalarınızdan başlıkları subprocess.run()
çıkarmak ve ardından sqlite'ın import ifadesini çalıştırmak için kullanmak olduğuna inanıyorum . Son kısım olduğundan en uygun olduğuna inanıyorum, bununla başlayacağım.
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)
Açıklama
Komut satırından aradığınız komut şudur sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
bir komut satırı işlemi çalıştırır. Argüman subprocess.run()
, bir komut olarak yorumlanan ve ardından tüm argümanlarının izlediği bir dizeler dizisidir.
sqlite3 my.db
veritabanını açar
-cmd
Veritabanından sonra gelen flag, sqlite programına birden fazla follow on komutunu aktarmanıza izin verir. Kabukta, her komutun tırnak içinde olması gerekir, ancak burada, sıranın kendi öğesi olmaları gerekir.
'.mode csv'
beklediğini yapar
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
içe aktarma komutudur.
Ne yazık ki, alt süreç tüm takipleri -cmd
alıntı dizeleri olarak aktardığından, bir Windows dizin yolunuz varsa ters eğik çizgileri ikiye katlamanız gerekir.
Sıyırma Başlıkları
Aslında sorunun ana noktası değil, ama işte kullandım. Yine, tüm dosyaları hiçbir noktada belleğe okumak istemedim:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)