Journal Rechercher des fichiers CSV (sans IA)

Posté par  .
Étiquettes : aucune
22
3
oct.
2026

Voilà un court journal pour vous parler d'un outil que je trouve à la fois excellent et extrêmement utile, à savoir DuckDB.

DuckDB est une base de données opensource, analytique, embarquée, orientée colonne et interopérable.

Si je prends mot par mot :

  • opensource : distribuée sous licence MIT

  • analytique : optimisée pour les requêtes analytiques (typiquement faire des aggrégats - pour l'exemple le plus banal, calculer le chiffre d'affaire par mois à partir d'une table factures), aux dépens des requêtes transactionnelles (qui lisent et modifient un petit nombre d'enregistrements, mais très fréquemment)

  • embarquée : même principe que sqlite, les bases de données sont des fichiers locaux. Il n'y a pas de serveur par défaut

  • orientée colonne : les données sont stockées colonne par colonne au lieu d'enregistrement par enregistrement. Cela permet notamment de faire des requêtes rapides sans index, et donc de rechercher n'importe quelle colonne

  • interopérable : elle permet de lire et écrire de nombreux formats de fichier (csv, parquet, json, excel, etc.) sur de nombreux supports (système de fichiers, stockage objet, http, etc.)

Pourquoi DuckDB c'est bien ?

DuckDB permet de lire, écrire et requêter des fichiers de données très simplement, mais fonctionne aussi avec de (très) gros fichiers, et tout ça rapidement.

Pour commencer, on peut utiliser DuckDB en mode interactif, soit avec une base de données en mémoire, soit avec une base de données dans un fichier :

$ duckdb
DuckDB v1.5.5 (Variegata)
Enter ".help" for usage hints.
memory D
^D

$ duckdb data.duck
DuckDB v1.5.5 (Variegata)
Enter ".help" for usage hints.
data D

mais aussi en one-liner :

$ duckdb -c 'select 1;'
┌───────┐
│   1   │
│ int32 │
├───────┤
│     1 │
└───────┘

ou avec un fichier de commandes (je vous passe la commande).

Ensuite, on peut lire des fichiers avec des défauts très raisonnables :

select * from read_csv('fichier.csv');
select * from read_json('fichier.ndjson');
-- etc.

Les types des colonne sont inférés automatiquement (texte, nombre, date, etc.). Et si ça ne convient pas on peut évidemment ajouter des options pour améliorer ça.

Si on veut faire des requêtes plus rapidement ou tout simplement ne pas répéter les commandes on peut stocker les données dans une table :

create table gruik as read_csv('fichier.csv');

Et ensuite on peut faire n'importe quelle requête.

Et bien sûr on peut exporter les données. Par exemple si on veut transformer un type de fichier on peut faire ça :

copy (select * from read_csv('a.tsv')) to 'out.json';

Et la recherche ?

DuckDB supporte non seulement les fonctionnalités habituelles du SQL standard, mais aussi la syntaxe pratique des bases de données analytiques (clause QUALIFY, mots-clés EXCLUDE ou autres dans la clause SELECT) et pas mal d'extensions qu'elle soient "core" ou communautaires (recherche en texte intégral, filtres bloom, interopérabilité avec d'autres choses…).

  • # excellent outil

    Posté par  . Évalué à 6 (+4/-0).

    Le positionnement est vraiment très intéressant : embarqué, lit plein de format, très rapide. Je l'avais expérimenté ici.

    Petite vigilance quand même car la boite qui employait l'équipe de développement a été acheté par AWS, pour en faire quoi …

  • # Toute la colonne, pas les autres

    Posté par  . Évalué à -3 (+2/-2).

    Sans index, un filtre lit quand même toute la colonne concernée. Ce qui tombe, ce sont les autres colonnes du fichier : sur un export large où on ne garde que deux champs, le volume lu chute. Si le filtre doit parcourir la colonne entière, le temps reste linéaire.

    • [^] # Re: Toute la colonne, pas les autres

      Posté par  . Évalué à 3 (+2/-0).

      Si le filtre doit parcourir la colonne entière, le temps reste linéaire.

      La complexité algorithmique reste linéaire. Par contre, et je trouve ça fascinant, c'est que la lecture est tellement rapide (grâce à la localité des données et le filtrage qui est souvent fait avec des instructions SIMD), que bien que la complexité algorithmique soit naze, ça reste rapide.

      D'ailleurs les bases de données colonne ne supportent pas (du moins les plus courantes comme clickhouse, duckdb, bigquery, etc.) les index BTree.

      Il y a cependant des optimisations, mais qui la plupart du temps n'affectent pas la complexité algorithmique (skip indexes, tri selon la clé primaire, parallélisation).

  • # Autopromotion : mon traitement des CSV

    Posté par  (site web personnel) . Évalué à 7 (+5/-0).

    Je profite du journal pour parler d’un projet que j’ai commencé il y a plus de quatre ans pour traiter des fichiers CSV, les mettre en relation, et produire… un autre CSV :

    https://git.chimrod.com/importer.git/about/?h=main

    Je n’avais pas retenu la syntaxe SQL et ait choisi de faire un fichier de configuration pour chaque opération de transformation (même si j’utilise une base SQLite sous le capot).

    L’idée est de préparer le fichier de règle (qui contient à la fois les sources à utiliser, les règles de filtrages, et les opérations de génération), puis lancer le traitement. C’est plus lourd, mais ça correspondait à mon cas d’usage (possibilité de versionner le traitement, reproductibilité etc). Je le comparerai davantage avec une utilisation des feuilles de calculs : si vous utilisez tous les jours RECHERCHEV, EQUIV et INDEX, ça devrait vous intéresser !

    Le code est stable et a « mangé » plusieurs centaines de milliers de lignes, mais dans ma tête ça reste un « outil » qui n’a jamais eu de nom…

  • # CSV et SGBD

    Posté par  (site web personnel) . Évalué à 4 (+2/-0).

    Il y a plein de possibilité. Cf ce journal et ses commentaires : https://linuxfr.org/users/montaigne/journaux/autocsv2sql-un-utilitaire-pour-convertir-ses-csv-sans-se-poser-de-question-ecris-en-ocaml

    Adhérer à l'April, ça vous tente ?

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.