Ви праві, що .import
це шлях, але це команда з оболонки SQLite3.exe. Багато відповідей на це запитання стосуються натільних циклів python, але якщо ваші файли великі (мої записи - 10 ^ 6 - 10 ^ 7), ви хочете уникати читання всього в пандах або з використанням природного списку пітонів для розуміння / циклу (хоча я їх не встиг порівняти).
Для великих файлів я вважаю, що найкращим варіантом є заздалегідь створити порожню таблицю за допомогою sqlite3.execute("CREATE TABLE...")
, зніміть заголовки з CSV-файлів, а потім використовувати subprocess.run()
для виконання заяви імпорту sqlite. Оскільки остання частина - я вважаю найбільш доречною, я розпочну з цього.
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)
Пояснення
У командному рядку шукана команда sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
запускає процес командного рядка. Аргумент до subprocess.run()
- це послідовність рядків, які інтерпретуються як команда, а потім - всі її аргументи.
sqlite3 my.db
відкриває базу даних
-cmd
прапор після бази даних дозволяє передавати кілька команд слідування за програмою sqlite. У оболонці кожна команда повинна бути в лапках, але тут вони просто повинні бути власним елементом послідовності
'.mode csv'
робить те, що ви очікували
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
- команда імпорту.
На жаль, оскільки підпроцес передає всі подальші дії -cmd
як цитовані рядки, вам потрібно подвоїти зворотні риски, якщо у вас є шлях до каталогу Windows.
Зачистки заголовків
Насправді не головний пункт питання, але ось що я використав. Знову ж таки, я не хотіла в будь-який момент читати цілі файли в пам'яті:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)