Vous avez raison, c'est .import
la voie à suivre, mais c'est une commande du shell SQLite3.exe. Un grand nombre des principales réponses à cette question impliquent des boucles python natives, mais si vos fichiers sont volumineux (les miens sont de 10 ^ 6 à 10 ^ 7 enregistrements), vous voulez éviter de tout lire dans des pandas ou d'utiliser une compréhension / boucle de liste python native (bien que je ne les ai pas chronométrés pour comparaison).
Pour les fichiers volumineux, je pense que la meilleure option est de créer la table vide à l'avance en utilisant sqlite3.execute("CREATE TABLE...")
, de supprimer les en-têtes de vos fichiers CSV, puis de l'utiliser subprocess.run()
pour exécuter la déclaration d'importation de sqlite. Puisque la dernière partie est, je crois, la plus pertinente, je vais commencer par là.
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)
Explication
À partir de la ligne de commande, la commande que vous recherchez est sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
exécute un processus de ligne de commande. L'argument to subprocess.run()
est une séquence de chaînes qui sont interprétées comme une commande suivie de tous ses arguments.
sqlite3 my.db
ouvre la base de données
-cmd
flag après que la base de données vous permet de transmettre plusieurs commandes de suivi au programme sqlite. Dans le shell, chaque commande doit être entre guillemets, mais ici, elles doivent juste être leur propre élément de la séquence
'.mode csv'
fait ce que vous attendez
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
est la commande d'importation.
Malheureusement, puisque le sous-processus transmet toutes les suites à des -cmd
chaînes entre guillemets, vous devez doubler vos barres obliques inverses si vous avez un chemin de répertoire Windows.
En-têtes de décapage
Pas vraiment le point principal de la question, mais voici ce que j'ai utilisé. Encore une fois, je ne voulais à aucun moment lire tous les fichiers en mémoire:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)