Vous avez raison. .import
est la meilleure solution, mais il s'agit d'une commande du programme de ligne de commande SQLite3. Un grand nombre des meilleures réponses à cette question impliquent des boucles python natives, mais si vos fichiers sont volumineux (les miens comptent 10^6 à 10^7 enregistrements), vous voudrez éviter de tout lire dans pandas ou d'utiliser une compréhension de liste/boucle python native (bien que je ne les ai pas chronométrés pour comparaison).
Pour les gros fichiers, je pense que la meilleure option est d'utiliser subprocess.run()
pour exécuter la commande d'importation de sqlite. Dans l'exemple ci-dessous, je suppose que la table existe déjà, mais le fichier csv a des en-têtes dans la première ligne. Voir .import
docs pour plus d'informations.
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 --skip 1 ' + str(csv_file).replace('\\','\\\\')
+' <table_name>'],
capture_output=True)
_note d'édition : les fonctions de sqlite3 .import
a été améliorée de sorte qu'elle peut traiter la première rangée comme des noms d'en-tête ou même sauter la première x (nécessite une version >=3.32, comme indiqué dans la rubrique cette réponse . Si vous avez une ancienne version de sqlite3, vous devrez peut-être d'abord créer la table, puis supprimer la première ligne du csv avant de l'importer. Le site --skip 1
donnera une erreur avant la version 3.32._
Explication
Depuis 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 en ligne de commande. L'argument de subprocess.run()
est une séquence de chaînes de caractères qui sont interprétées comme une commande suivie de tous ses arguments.
-
sqlite3 my.db
ouvre la base de données
-
-cmd
après la base de données vous permet de passer plusieurs commandes de suivi au programme sqlite. Dans l'interpréteur de commandes, chaque commande doit être entre guillemets, mais ici, elles doivent simplement être leur propre élément de la séquence.
-
'.mode csv'
fait ce que l'on attend d'elle
-
'.import --skip 1'+str(csv_file).replace('\\','\\\\')+' <table_name>'
est la commande d'importation.
Malheureusement, puisque le sous-processus transmet tous les suivis à -cmd
en tant que chaînes entre guillemets, vous devez doubler vos antislashs si vous avez un chemin de répertoire Windows.
Décapage des en-têtes
Ce n'est pas vraiment le point principal de la question, mais voici ce que j'ai utilisé. Encore une fois, je ne voulais pas lire les fichiers entiers en mémoire à un moment donné :
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)
4 votes
Veuillez fournir le réel qui n'a pas fonctionné et la commande réel message d'erreur. "import...." peut être n'importe quoi. "cannot work" est trop vague pour que nous puissions le deviner. Sans détails, nous ne pouvons pas vous aider.
3 votes
La commande réelle comme je l'ai dit est ".import" et il dit erreur de syntaxe nouveau ".import".
14 votes
Veuillez afficher la commande réelle dans la question. Veuillez afficher le message d'erreur réel dans la question. Veuillez ne pas ajouter de commentaires qui ne font que répéter les choses. Veuillez mettre à jour la question avec un copier-coller de ce que vous faites réellement.
0 votes
FWIW
.import
est la commande pour importer des fichiers dans le shell interactif SQLite.