Eu tenho um arquivo CSV e quero importar em massa esse arquivo para meu banco de dados sqlite3 usando Python. o comando é ".import .....". mas parece que não pode funcionar assim. Alguém pode me dar um exemplo de como fazer isso no sqlite3? Estou usando o Windows apenas no caso. obrigado
106
Respostas:
fonte
not all arguments converted during string formatting
quando tento esse método.Criar uma conexão sqlite com um arquivo no disco é deixado como um exercício para o leitor ... mas agora existe um two-liner possibilitado pela biblioteca pandas
fonte
df
então encurtei seu exemplo para:pandas.read_csv(csvfile).to_sql(table_name, conn, if_exists='append', index=False)
Meus 2 centavos (mais genérico):
fonte
O
.import
comando é um recurso da ferramenta de linha de comando sqlite3. Para fazer isso em Python, você deve simplesmente carregar os dados usando quaisquer recursos que o Python tenha, como o módulo csv , e inserir os dados normalmente.Dessa forma, você também tem controle sobre quais tipos são inseridos, ao invés de confiar no comportamento aparentemente não documentado do sqlite3.
fonte
fonte
Muito obrigado pela resposta de bernie ! Tive que ajustar um pouco - aqui está o que funcionou para mim:
Meu arquivo de texto (PC.txt) tem a seguinte aparência:
fonte
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, usarsubprocess.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()
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 parasubprocess.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:
fonte
Baseado na solução Guy L (Love it), mas pode lidar com campos de escape.
fonte
Você pode fazer isso usando
blaze
e de formaodo
eficienteOdo irá armazenar o arquivo csv em
data.db
(banco de dados sqlite) sob o esquemadata
Ou você usa
odo
diretamente, semblaze
. Qualquer maneira está bem. Leia esta documentaçãofonte
Se o arquivo CSV deve ser importado como parte de um programa Python, para simplicidade e eficiência, você pode usar
os.system
as linhas sugeridas a seguir:A questão é que ao especificar o nome do arquivo do banco de dados, os dados serão salvos automaticamente, assumindo que não haja erros ao lê-los.
fonte
fonte
por uma questão de simplicidade, você pode usar a ferramenta de linha de comando sqlite3 do Makefile do seu projeto.
make test.sql3
em seguida, cria o banco de dados sqlite a partir de um arquivo test.csv existente, com uma única tabela "teste". você pode entãomake test.dump
verificar o conteúdo.fonte
Descobri que pode ser necessário quebrar a transferência de dados do csv para o banco de dados em blocos para não ficar sem memória. Isso pode ser feito assim:
fonte