Tiene razón, ese .import
es el camino a seguir, pero ese es un comando del shell SQLite3.exe. Muchas de las respuestas principales a esta pregunta involucran bucles de Python nativos, pero si sus archivos son grandes (los míos son de 10 ^ 6 a 10 ^ 7 registros), desea evitar leer todo en pandas o usar un bucle / comprensión de lista de Python nativo (aunque no los cronometré para compararlos).
Para archivos grandes, creo que la mejor opción es crear la tabla vacía de antemano usando sqlite3.execute("CREATE TABLE...")
, quitar los encabezados de sus archivos CSV y luego usar subprocess.run()
para ejecutar la declaración de importación de sqlite. Dado que la última parte es, creo, la más pertinente, comenzaré con eso.
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)
Explicación
Desde la línea de comandos, el comando que está buscando es sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
ejecuta un proceso de línea de comandos. El argumento de subprocess.run()
es una secuencia de cadenas que se interpretan como un comando seguido de todos sus argumentos.
sqlite3 my.db
abre la base de datos
-cmd
flag después de que la base de datos le permite pasar múltiples comandos de seguimiento al programa sqlite. En el shell, cada comando debe estar entre comillas, pero aquí, solo deben ser su propio elemento de la secuencia.
'.mode csv'
hace lo que esperabas
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
es el comando de importación.
Desafortunadamente, dado que el subproceso pasa todos los seguimientos -cmd
como cadenas entre comillas, debe duplicar sus barras diagonales inversas si tiene una ruta de directorio de Windows.
Eliminación de encabezados
No es realmente el punto principal de la pregunta, pero esto es lo que usé. Nuevamente, no quería leer todos los archivos en la memoria en ningún momento:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)