> ## Content Index
> Fetch the complete content index at: https://www.idriss-benbassou.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Les seeds dbt : charger des données de référence depuis un CSV
- URL: https://www.idriss-benbassou.com/dbt-seeds-csv-data-donnees-reference/
- Published: 2026-06-19T21:18:03.000Z
- Updated: 2026-06-19T21:21:00.000Z
- Author: Idriss BENBASSOU
- Tags: dbt, #rating-1

Depuis le début de la formation, on a appris à dbt où trouver les données avec les [**sources**](https://www.idriss-benbassou.com/dbt-sources-staging-source-ref-premiere-couche/), puis à les nettoyer dans le [**staging**](https://www.idriss-benbassou.com/dbt-sources-staging-source-ref-premiere-couche/). Ces données arrivent d'un système externe (un ERP, un CRM, un outil d'ingestion) et dbt ne fait que les lire.

Mais il y a une autre catégorie de données. Des petites tables de référence qui n'ont pas de système source comme par exemple une correspondance entre un code statut et son libellé, une liste de pays ou un fichier de mapping.

## C'est quoi un seed

Un seed, c'est un fichier CSV qu'on place dans le projet dbt, et que dbt charge dans l'entrepôt avec une commande. Une fois chargé, c'est une table comme une autre, qu'on référence avec `ref()`.

La différence avec une source est simple :

- Une source, c'est une table déjà présente dans Snowflake par exemple. dbt la lit, il ne la crée pas.
- Un seed, c'est un CSV qui vit dans ton dépôt Git, et que c'est dbt qui charge.

## Quand utiliser un seed (et quand surtout pas)

C'est le point à bien comprendre, parce que c'est là qu'on fait des bêtises.

Un seed est fait pour de la petite donnée de référence, qui ne bouge pas dans le temps ou trés rarement, et qu'on veut maintenir à la main, par exemple :

- Une table de mapping des libellés des codes pays.
- Une liste fermée (les jours fériés ou une liste de comptes de test à exclure)

Un seed n'est pas fait pour :

- De la vraie donnée métier qui arrive d'un système (ça, c'est une source)
- Des gros volumes. Un CSV de millions de lignes dans Git, c'est non.
- De la donnée qui change souvent. Car dans ce cas, il faut une source et pas un seed.

## Notre premier seed

On reprend le projet. Dans `stg_orders`, on a une colonne `statut` qui vaut `completed` ou `pending` mais on veut leur associer un libellé propre et un indicateur pour dire si la commande est payée ou non.

Cette correspondance n'a aucune source, c'est une décision métier. Donc un seed.

Au niveau du dossier `seeds/` à la racine du projet on va créer le fichier `statuts_commande.csv` :

```text
statut,libelle,est_paye
completed,Terminée,true
pending,En attente,false
cancelled,Annulée,false

```

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/06/image-36.png)

On ajoute même `cancelled`, qui n'existe pas encore dans nos commandes mais qu'on anticipe. Un seed peut contenir plus de valeurs que la donnée réelle, ce n'est pas un souci.

Maintenant, on charge le fichier :

```powershell
dbt seed

```

dbt lit le CSV, crée une table `statuts_commande` dans le schéma `dev`, et insère les trois lignes. Va voir dans Snowsight, déplie `ANALYTICS` \> `DEV` pour la table avec son contenu.

![dbt seed](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/06/image-37.png)

dbt seed

💡

`dbt seed` est la commande qui charge les CSV.

## Brancher le seed à un modèle avec `ref()`

Un seed se référence exactement comme un modèle, avec `ref()`. Pas de `source()` ici, puisque c'est dbt qui a créé la table.

Crée un modèle `models/marts/mart_orders_enrichi.sql` qui joint les commandes à leur libellé :

```sql
with commandes as (
    select * from {{ ref('stg_orders') }}
),

statuts as (
    select * from {{ ref('statuts_commande') }}
)

select
    c.order_id,
    c.customer_id,
    c.montant,
    c.statut,
    s.libelle   as statut_libelle,
    s.est_paye
from commandes c
left join statuts s
    on c.statut = s.statut

```

Lance le build de ce modèle :

```powershell
dbt run --select mart_orders_enrichi

```

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/06/image-38.png)

dbt sait que `mart_orders_enrichi` dépend du seed et du staging, grâce aux deux `ref()`.

## Forcer les types avec `column_types`

Un piège classique des seeds. Par défaut, dbt devine le type de chaque colonne à partir du contenu du CSV. La plupart du temps ça marche, mais parfois il se trompe, par exemple un code postal `01000` qu'il transforme en nombre `1000`, ou notre `est_paye` qu'on veut en booléen et pas en texte.

Pour ne rien laisser au hasard, on déclare les types dans le `dbt_project.yml` :

```yaml
seeds:
  dbt_projet:
    statuts_commande:
      +column_types:
        statut: varchar
        libelle: varchar
        est_paye: boolean

```

Au prochain `dbt seed`, dbt crée la table avec exactement ces types.

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/06/image-39.png)

Le bloc `seeds:` dans `dbt_project.yml` fonctionne comme le bloc `models:` qu'on a vu pour les matérialisations. On peut configurer un seed précis (comme ici) ou tout un dossier de seeds d'un coup. 

## Documenter et tester un seed

Un seed est une table dbt à part entière, donc il a droit à sa description et à ses tests, exactement comme un modèle. On reprend la logique du fichier de propriétés qu'on a vue pour les tests et la doc.

Crée `seeds/_seeds.yml` :

```yaml
version: 2

seeds:
  - name: statuts_commande
    description: "Référentiel des statuts de commande"
    columns:
      - name: statut
        description: "Code du statut."
        data_tests:
          - unique
          - not_null
      - name: est_paye
        description: "Vrai si le statut correspond à une commande payée."
        data_tests:
          - not_null

```

Au prochain `dbt test`, dbt vérifie que le code statut est unique et non nul dans le référentiel. Un doublon dans le CSV serait identifié rapidement.

Et on peut aller un cran plus loin. Souviens-toi du test `relationships` de l'article sur les tests. On peut vérifier que chaque statut présent dans les commandes existe bien dans le référentiel. Sur `stg_orders`, dans son fichier de propriétés :

```yaml
- name: statut
  data_tests:
    - relationships:
        arguments:
          to: ref('statuts_commande')
          field: statut

```

Le jour où une commande arrive avec un statut inconnu du référentiel (`refunded` par exemple), le test échoue, et on sait qu'il faut ajouter une ligne au CSV. Le seed devient la liste de référence officielle.

## `dbt seed`, `dbt run`, `dbt build`

Est-ce que les seeds se rechargent tout seuls ?

Non, et c'est important. `dbt run` ne touche pas aux seeds, il ne construit que les modèles. Si on modifie le CSV, il faut relancer `dbt seed` pour que la table soit mise à jour.

La bonne nouvelle, c'est que `dbt build` lui s'occupe de tout dans le bon ordre donc il charge les seeds, construit les modèles, lance les tests et les snapshots. Voir [l'article sur le déploiement.](https://www.idriss-benbassou.com/dbt-deploiement-git-build-production/)

💡

Par défaut, un `dbt seed` recharge toute la table à chaque fois (il la remplace) donc c'est parfait pour les petites tables de référence. Mais ne tente jamais d'utiliser un seed pour de la donnée qui grossit, on rechargerait tout à chaque exécution.

## Ce qu'on a fait

Récap. de cet article :

- Comprendre la différence entre une source (donnée externe que dbt lit) et un seed (CSV que dbt charge)
- Créer un seed dans `seeds/` et le charger avec `dbt seed`
- Brancher le seed à un modèle avec `ref()`, sans écrire le mapping en dur
- Forcer les types avec `column_types` pour éviter les mauvaises surprises
- Documenter et tester le seed, et vérifier l'intégrité avec un test `relationships`
- Retenir que `dbt run` ignore les seeds, mais que `dbt build` les enchaîne

## Aller plus loin

Cet article fait partie de la formation dbt complète, du premier modèle au déploiement en production.

👉 [Suivre toute la formation dbt](https://www.idriss-benbassou.com/formation-dbt/)

dbt tourne sur Snowflake dans ce parcours. Pour maîtriser le socle (warehouses, rôles, ingestion) :

👉 [Accéder à la Formation Snowflake](https://www.idriss-benbassou.com/formation-snowflake/)

Et pour t'entraîner en conditions d'examen, la certification dbt Analytics Engineering teste précisément les seeds et la gestion des données de référence.

👉 [Préparer la certification dbt sur DataCertification.fr](https://datacertification.fr/certifications/dbt?ref=idriss-benbassou.com)

Tu veux que je t'accompagne sur ton projet data (Snowflake, dbt, modélisation, industrialisation) ?

👉 [Réserver un appel de 30 minutes](https://calendly.com/idriss-benbassou-datavio/30min?ref=idriss-benbassou.com)

---

## Questions fréquentes

#### Quelle différence entre un seed et une source en dbt ?

Une source est une table déjà présente dans l'entrepôt, alimentée par un système externe, que dbt se contente de lire. Un seed est un fichier CSV qui vit dans le projet dbt et que c'est dbt qui charge dans l'entrepôt avec `dbt seed`.

#### Où placer le fichier CSV d'un seed ?

Dans le dossier `seeds/` à la racine du projet, au même niveau que `models/`. dbt prend le nom du fichier (sans l'extension) comme nom de table. Un fichier `statuts_commande.csv` devient une table `statuts_commande`, qu'on référence ensuite avec `ref('statuts_commande')`.

#### Comment charger un seed dans Snowflake ?

Avec la commande `dbt seed`. dbt lit le CSV, crée la table dans le schéma cible et insère les lignes. Si on modifie le CSV, il faut relancer `dbt seed` pour mettre à jour la table. `dbt run` ne recharge pas les seeds, mais `dbt build` les enchaîne automatiquement avant les modèles.

#### Comment éviter que dbt se trompe sur le type d'une colonne de seed ?

Par défaut, dbt devine les types à partir du contenu du CSV, mais dans certain cas le type peut être faux. Pour fixer ça, on déclare les types dans le `dbt_project.yml` sous le seed concerné, avec la clé `+column_types`. dbt crée alors la table avec exactement les types demandés.

#### Peut-on tester et documenter un seed ?

Oui, un seed est une table dbt à part entière. On lui ajoute une description et des tests dans un fichier de propriétés (`unique`, `not_null` sur la clé, par exemple). On peut même tester avec `relationships` que chaque valeur utilisée dans les modèles existe bien dans le seed, ce qui en fait une vraie liste de référence contrôlée.

#### Un seed, c'est pour quel volume de données ?

Pour de la petite donnée, quelques lignes à quelques centaines au maximum. Un seed se recharge entièrement à chaque `dbt seed` et vit dans Git, donc il n'est pas fait pour de gros volumes ni pour de la donnée qui change souvent. Au-delà, c'est le signe qu'il faut une vraie source alimentée par un outil d'ingestion.

####