Você está certo, esse .import
é o caminho a seguir, mas esse é um comando do shell SQLite3.exe. Muitas das principais respostas a esta pergunta envolvem loops nativos do python, mas se seus arquivos forem grandes (os meus são de 10 ^ 6 a 10 ^ 7 registros), você deve evitar ler tudo nos pandas ou usar uma compreensão / loop de lista nativa do python (embora eu não os tenha cronometrado para comparação).
Para arquivos grandes, acredito que a melhor opção é criar a tabela vazia com antecedência usando sqlite3.execute("CREATE TABLE...")
, retirar os cabeçalhos de seus arquivos CSV e, em seguida, usar subprocess.run()
para executar a instrução de importação do sqlite. Já que a última parte é, creio, a mais pertinente, começarei por aí.
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)
Explicação
Na linha de comando, o comando que você está procurando é sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
executa um processo de linha de comando. O argumento para subprocess.run()
é uma sequência de strings que são interpretadas como um comando seguido por todos os seus argumentos.
sqlite3 my.db
abre o banco de dados
-cmd
após o banco de dados permitir que você passe vários comandos de acompanhamento para o programa sqlite. No shell, cada comando deve estar entre aspas, mas aqui, eles só precisam ser seus próprios elementos da sequência
'.mode csv'
faz o que você esperaria
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
é o comando de importação.
Infelizmente, uma vez que o subprocesso passa todos os subprocessos -cmd
como strings entre aspas, você precisa dobrar as barras invertidas se tiver um caminho de diretório do Windows.
Decapando Cabeçalhos
Não é realmente o ponto principal da pergunta, mas aqui está o que usei. Novamente, eu não queria ler todos os arquivos na memória em nenhum momento:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)