- À propos de l'importation et de l'exportation CSV - SQLite avec Python
- Créer une base de données SQLite et une table
- Préparer un fichier CSV à importer dans SQLite
- Importer un fichier CSV dans SQLite avec csv.reader()
- Importer plusieurs lignes efficacement avec executemany()
- Vérifier et convertir les données avant l'importation
- Exporter une table SQLite vers un fichier CSV
- Exporter le résultat d'une requête SQL vers CSV
- Créer un programme complet d'importation et d'exportation CSV - SQLite
- À retenir !
1. À propos de l'importation et de l'exportation CSV - SQLite avec Python
Python fournit dans sa bibliothèque standard les modules csv et sqlite3. Leur utilisation conjointe permet de transférer facilement des données entre un fichier CSV et une base de données SQLite, sans installer de bibliothèque supplémentaire.
L'importation CSV vers SQLite consiste à lire les lignes d'un fichier CSV puis à les insérer dans une table de la base de données. L'exportation SQLite vers CSV réalise l'opération inverse : une requête SQL récupère des enregistrements qui sont ensuite écrits dans un fichier CSV.
Le programme suivant vérifie que les deux modules nécessaires sont disponibles.
1 2 3 4 5 | import csv import sqlite3 print("Module CSV :", csv.__name__) print("Module SQLite :", sqlite3.__name__) |
Sortie :
1 2 | Module CSV : csv Module SQLite : sqlite3 |
Cette association est particulièrement utile pour importer des données provenant d'un tableur, sauvegarder le contenu d'une table, produire des fichiers destinés à Excel ou LibreOffice et transférer des données entre différentes applications.
2. Créer une base de données SQLite et une table
Avant d'importer des données CSV, nous allons créer une base SQLite nommée ecole.db. La fonction sqlite3.connect() ouvre la base si elle existe et la crée automatiquement dans le cas contraire.
Le programme suivant crée une table etudiants possédant les colonnes id, nom, age, ville et note. L'identifiant est généré automatiquement par SQLite.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute(""" CREATE TABLE IF NOT EXISTS etudiants ( id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT NOT NULL, age INTEGER, ville TEXT, note REAL ) """) connexion.commit() connexion.close() print("Base et table créées avec succès.") |
Sortie :
1 | Base et table créées avec succès. |
L'appel à commit() valide les modifications apportées à la base. La méthode close() ferme ensuite la connexion.
Nous pouvons vérifier la présence de la table en interrogeant le catalogue interne de SQLite.
1 2 3 4 5 6 7 8 9 10 11 12 13 | import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute(""" SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'etudiants' """) print(curseur.fetchone()) connexion.close() |
Sortie :
1 | ('etudiants',) |
La base de données est maintenant prête à recevoir les données provenant du fichier CSV.
3. Préparer un fichier CSV à importer dans SQLite
Considérons un fichier nommé etudiants.csv. Sa première ligne contient les noms des colonnes et les lignes suivantes contiennent les données à importer.
Le fichier utilisé dans nos exemples possède le contenu suivant.
1 2 3 4 5 | nom,age,ville,note Amine,21,Oujda,15.5 Sara,20,Rabat,17 Yassine,22,Fès,13.5 Lina,19,Casablanca,18 |
Sortie :
1 | Une ligne d'en-tête et quatre lignes de données sont disponibles pour l'importation. |
Avant l'importation, nous pouvons vérifier le contenu du fichier avec csv.reader(). La fonction next() permet ici de récupérer séparément l'en-tête.
1 2 3 4 5 6 7 8 9 10 | import csv with open("etudiants.csv", "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) entete = next(lecteur, None) print("En-tête :", entete) for ligne in lecteur: print(ligne) |
Sortie :
1 2 3 4 5 | En-tête : ['nom', 'age', 'ville', 'note'] ['Amine', '21', 'Oujda', '15.5'] ['Sara', '20', 'Rabat', '17'] ['Yassine', '22', 'Fès', '13.5'] ['Lina', '19', 'Casablanca', '18'] |
Les données retournées par csv.reader() sont des chaînes de caractères. Nous pourrons donc convertir les colonnes age et note avant leur insertion dans SQLite.
4. Importer un fichier CSV dans SQLite avec csv.reader()
Pour réaliser une importation CSV vers SQLite, nous ouvrons simultanément le fichier CSV et la base de données. Chaque ligne lue est ensuite insérée avec une requête INSERT INTO.
Le programme suivant ignore l'en-tête avec next(), convertit l'âge en entier et la note en nombre réel, puis insère chaque étudiant dans la table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import csv import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() with open("etudiants.csv", "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) next(lecteur, None) for nom, age, ville, note in lecteur: curseur.execute( "INSERT INTO etudiants (nom, age, ville, note) VALUES (?, ?, ?, ?)", (nom, int(age), ville, float(note)) ) connexion.commit() connexion.close() print("Importation terminée.") |
Sortie :
1 | Importation terminée. |
Les points d'interrogation présents dans la requête sont des paramètres SQL. Il est préférable de transmettre les valeurs séparément plutôt que de construire une requête SQL par concaténation de chaînes.
Nous pouvons maintenant interroger la table pour vérifier les enregistrements importés.
1 2 3 4 5 6 7 8 9 10 11 | import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute("SELECT id, nom, age, ville, note FROM etudiants") for ligne in curseur.fetchall(): print(ligne) connexion.close() |
Sortie possible :
1 2 3 4 | (1, 'Amine', 21, 'Oujda', 15.5) (2, 'Sara', 20, 'Rabat', 17.0) (3, 'Yassine', 22, 'Fès', 13.5) (4, 'Lina', 19, 'Casablanca', 18.0) |
Les données du fichier CSV sont désormais enregistrées dans une véritable table SQLite et peuvent être interrogées avec le langage SQL.
5. Importer plusieurs lignes efficacement avec executemany()
Lorsque plusieurs lignes doivent être insérées, la méthode executemany() permet de transmettre une collection de paramètres à une même requête SQL. Cette approche évite d'appeler explicitement execute() dans une boucle pour chaque insertion.
Dans l'exemple suivant, nous lisons les données CSV, nous les convertissons puis nous les plaçons dans une liste avant de les transmettre à executemany().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import csv import sqlite3 donnees = [] with open("etudiants.csv", "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) next(lecteur, None) for nom, age, ville, note in lecteur: donnees.append((nom, int(age), ville, float(note))) connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.executemany( "INSERT INTO etudiants (nom, age, ville, note) VALUES (?, ?, ?, ?)", donnees ) connexion.commit() connexion.close() print("Nombre de lignes importées :", len(donnees)) |
Sortie :
1 | Nombre de lignes importées : 4 |
Dans un test réel, il faut éviter de réexécuter cet exemple sur une table contenant déjà les mêmes étudiants si l'on ne souhaite pas créer de doublons. On peut repartir d'une table vide, définir des contraintes d'unicité adaptées au modèle de données ou prévoir une stratégie explicite de mise à jour.
Pour connaître le nombre total d'enregistrements présents dans la table, nous pouvons utiliser COUNT(*).
1 2 3 4 5 6 7 8 9 10 | import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute("SELECT COUNT(*) FROM etudiants") nombre = curseur.fetchone()[0] print("Nombre d'enregistrements :", nombre) connexion.close() |
Sortie possible :
1 | Nombre d'enregistrements : 4 |
Cette sortie suppose que la table contenait quatre étudiants et que les données n'ont pas été importées plusieurs fois.
6. Vérifier et convertir les données avant l'importation
Un fichier CSV provenant d'une source externe peut contenir des lignes incomplètes, des nombres invalides ou des champs vides. Il est donc préférable de vérifier les données avant de les insérer dans SQLite.
Le programme suivant contrôle que chaque ligne contient quatre colonnes et que l'âge et la note peuvent être convertis respectivement en int et float.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import csv donnees_valides = [] with open("etudiants.csv", "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) next(lecteur, None) for numero, ligne in enumerate(lecteur, start=2): if len(ligne) != 4: print("Ligne ignorée :", numero) continue nom, age, ville, note = ligne try: age = int(age) note = float(note) donnees_valides.append((nom, age, ville, note)) except ValueError: print("Valeur incorrecte à la ligne :", numero) print("Lignes valides :", len(donnees_valides)) |
Sortie :
1 | Lignes valides : 4 |
Une fois les données contrôlées, nous pouvons les insérer dans SQLite avec executemany().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.executemany( "INSERT INTO etudiants (nom, age, ville, note) VALUES (?, ?, ?, ?)", donnees_valides ) connexion.commit() connexion.close() print("Les données valides ont été importées.") |
Sortie :
1 | Les données valides ont été importées. |
Pour une importation importante, il est également utile de gérer les erreurs SQLite. Le contexte transactionnel de la connexion peut faciliter l'annulation automatique d'une transaction lorsqu'une exception survient.
1 2 3 4 5 6 7 8 9 10 11 12 | import sqlite3 try: with sqlite3.connect("ecole.db") as connexion: curseur = connexion.cursor() curseur.executemany( "INSERT INTO etudiants (nom, age, ville, note) VALUES (?, ?, ?, ?)", donnees_valides ) print("Importation validée.") except sqlite3.Error as erreur: print("Erreur SQLite :", erreur) |
Sortie possible :
1 | Importation validée. |
La validation des données avant l'insertion permet d'obtenir une base plus cohérente et facilite le diagnostic lorsqu'un fichier CSV contient des informations incorrectes.
7. Exporter une table SQLite vers un fichier CSV
L'opération inverse consiste à effectuer une exportation SQLite vers CSV. Nous récupérons les lignes d'une table avec SELECT puis nous utilisons csv.writer() pour les enregistrer dans un fichier.
Le programme suivant exporte l'ensemble de la table etudiants vers le fichier export_etudiants.csv.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import csv import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute("SELECT id, nom, age, ville, note FROM etudiants") lignes = curseur.fetchall() with open("export_etudiants.csv", "w", encoding="utf-8", newline="") as fichier: writer = csv.writer(fichier) writer.writerow(["id", "nom", "age", "ville", "note"]) writer.writerows(lignes) connexion.close() print("Exportation terminée.") print("Nombre de lignes exportées :", len(lignes)) |
Sortie possible :
1 2 | Exportation terminée. Nombre de lignes exportées : 4 |
Le fichier CSV obtenu contient alors l'en-tête suivi des enregistrements extraits de SQLite.
1 2 3 4 5 | id,nom,age,ville,note 1,Amine,21,Oujda,15.5 2,Sara,20,Rabat,17.0 3,Yassine,22,Fès,13.5 4,Lina,19,Casablanca,18.0 |
Sortie :
1 | La table SQLite est représentée sous forme tabulaire dans le fichier CSV. |
Pour un très grand résultat, il n'est pas obligatoire d'utiliser fetchall(). Le curseur SQLite peut être parcouru directement afin d'écrire progressivement les lignes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import csv import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute("SELECT id, nom, age, ville, note FROM etudiants") with open("export_etudiants.csv", "w", encoding="utf-8", newline="") as fichier: writer = csv.writer(fichier) writer.writerow(["id", "nom", "age", "ville", "note"]) for ligne in curseur: writer.writerow(ligne) connexion.close() print("Exportation ligne par ligne terminée.") |
Sortie :
1 | Exportation ligne par ligne terminée. |
Cette approche évite de charger explicitement l'ensemble du résultat dans une liste avant son écriture.
8. Exporter le résultat d'une requête SQL vers CSV
Il n'est pas nécessaire d'exporter toute une table. Nous pouvons exécuter une requête SQL contenant WHERE, ORDER BY ou d'autres clauses puis exporter uniquement son résultat.
Le programme suivant sélectionne les étudiants ayant une note supérieure ou égale à 15 et les classe par note décroissante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import csv import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute(""" SELECT nom, ville, note FROM etudiants WHERE note >= ? ORDER BY note DESC """, (15,)) resultats = curseur.fetchall() with open("bons_resultats.csv", "w", encoding="utf-8", newline="") as fichier: writer = csv.writer(fichier) writer.writerow(["nom", "ville", "note"]) writer.writerows(resultats) connexion.close() print("Nombre d'étudiants exportés :", len(resultats)) |
Sortie :
1 | Nombre d'étudiants exportés : 3 |
Avec les données de notre exemple, le fichier généré contient uniquement les étudiants répondant au critère demandé.
1 2 3 4 | nom,ville,note Lina,Casablanca,18.0 Sara,Rabat,17.0 Amine,Oujda,15.5 |
Sortie :
1 | Trois étudiants possédant une note supérieure ou égale à 15 ont été exportés. |
Nous pouvons également récupérer automatiquement les noms des colonnes retournées par une requête grâce à l'attribut cursor.description.
1 2 3 4 5 6 7 8 9 10 | import sqlite3 connexion = sqlite3.connect("ecole.db") curseur = connexion.cursor() curseur.execute("SELECT nom, age, ville, note FROM etudiants") colonnes = [description[0] for description in curseur.description] print(colonnes) connexion.close() |
Sortie :
1 | ['nom', 'age', 'ville', 'note'] |
Cette technique devient particulièrement pratique pour créer une fonction d'exportation générique capable de produire automatiquement l'en-tête du fichier CSV.
9. Créer un programme complet d'importation et d'exportation CSV - SQLite
Pour rendre le programme réutilisable, nous pouvons regrouper les opérations dans des fonctions. Une première fonction importe un fichier CSV dans SQLite et une seconde exporte les données de la table vers un nouveau fichier CSV.
Le programme suivant présente une version complète associant csv.reader(), csv.writer(), sqlite3 et des requêtes SQL paramétrées.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import csv import sqlite3 BASE = "ecole.db" def creer_table(): with sqlite3.connect(BASE) as connexion: connexion.execute(""" CREATE TABLE IF NOT EXISTS etudiants ( id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT NOT NULL, age INTEGER, ville TEXT, note REAL ) """) def importer_csv(nom_fichier): donnees = [] with open(nom_fichier, "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) next(lecteur, None) for nom, age, ville, note in lecteur: donnees.append((nom, int(age), ville, float(note))) with sqlite3.connect(BASE) as connexion: connexion.executemany( "INSERT INTO etudiants (nom, age, ville, note) VALUES (?, ?, ?, ?)", donnees ) return len(donnees) def exporter_csv(nom_fichier): with sqlite3.connect(BASE) as connexion: curseur = connexion.cursor() curseur.execute("SELECT id, nom, age, ville, note FROM etudiants") lignes = curseur.fetchall() with open(nom_fichier, "w", encoding="utf-8", newline="") as fichier: writer = csv.writer(fichier) writer.writerow(["id", "nom", "age", "ville", "note"]) writer.writerows(lignes) return len(lignes) creer_table() nb_importes = importer_csv("etudiants.csv") nb_exportes = exporter_csv("export_etudiants.csv") print("Lignes importées :", nb_importes) print("Lignes exportées :", nb_exportes) |
Sortie possible :
1 2 | Lignes importées : 4 Lignes exportées : 4 |
Cette sortie suppose une table initialement vide. Si le programme est exécuté plusieurs fois sans supprimer les données précédentes ou sans contrainte empêchant les doublons, de nouveaux enregistrements seront ajoutés à chaque importation.
Nous pouvons enfin vérifier directement les données exportées en relisant le fichier généré.
1 2 3 4 5 6 7 | import csv with open("export_etudiants.csv", "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) for ligne in lecteur: print(ligne) |
Sortie possible :
1 2 3 4 5 | ['id', 'nom', 'age', 'ville', 'note'] ['1', 'Amine', '21', 'Oujda', '15.5'] ['2', 'Sara', '20', 'Rabat', '17.0'] ['3', 'Yassine', '22', 'Fès', '13.5'] ['4', 'Lina', '19', 'Casablanca', '18.0'] |
Cette architecture peut ensuite être adaptée à des fichiers de produits, clients, commandes, notes scolaires ou tout autre ensemble de données tabulaires.
10. À retenir !
L'association des modules csv et sqlite3 permet de construire facilement une passerelle entre les fichiers CSV et une base de données SQLite. Les deux modules étant inclus dans la bibliothèque standard, aucune dépendance externe n'est nécessaire pour réaliser les opérations de base.
- csv.reader() permet de parcourir les lignes d'un fichier CSV.
- sqlite3.connect() permet d'ouvrir ou de créer une base SQLite.
- INSERT INTO permet d'insérer dans SQLite les données provenant du fichier CSV.
- Les requêtes SQL doivent utiliser des paramètres plutôt qu'une concaténation des valeurs dans la chaîne SQL.
- executemany() permet d'appliquer une même requête à plusieurs ensembles de paramètres.
- Les valeurs numériques provenant de csv.reader() peuvent être converties avec int() et float().
- SELECT permet de récupérer les données SQLite à exporter.
- csv.writer() et writerows() permettent d'écrire les résultats SQL dans un fichier CSV.
- cursor.description peut servir à récupérer automatiquement les noms des colonnes d'un résultat SQL.
- Il est recommandé de valider les données, de gérer les transactions et de prévoir une stratégie contre les doublons pour les importations réelles.
Le principe général d'une importation CSV vers SQLite peut être résumé par le programme suivant.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import csv import sqlite3 with open("etudiants.csv", "r", encoding="utf-8", newline="") as fichier: lecteur = csv.reader(fichier) next(lecteur, None) donnees = [ (nom, int(age), ville, float(note)) for nom, age, ville, note in lecteur ] with sqlite3.connect("ecole.db") as connexion: connexion.executemany( "INSERT INTO etudiants (nom, age, ville, note) VALUES (?, ?, ?, ?)", donnees ) print("Importation CSV vers SQLite terminée.") |
Sortie :
1 | Importation CSV vers SQLite terminée. |
L'opération inverse consiste à exécuter une requête SELECT puis à transmettre ses résultats à csv.writer().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import csv import sqlite3 with sqlite3.connect("ecole.db") as connexion: curseur = connexion.cursor() curseur.execute("SELECT id, nom, age, ville, note FROM etudiants") lignes = curseur.fetchall() with open("export.csv", "w", encoding="utf-8", newline="") as fichier: writer = csv.writer(fichier) writer.writerow(["id", "nom", "age", "ville", "note"]) writer.writerows(lignes) print("Exportation SQLite vers CSV terminée.") |
Sortie :
1 | Exportation SQLite vers CSV terminée. |
Auteur : Younes Derfoufi
Lieu de travail : CRMEF OUJDA
Site Web : www.tresfacile.net
Chaine YouTube : https://www.youtube.com/user/InformatiquesFacile
Me contacter : https://www.tresfacile.net/me-contacter/



