📊 Data

data-dbt-guide

Transformation de données avec dbt — models, tests, sources, macros et documentation automatisée.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- data-dbt-guide --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } data-dbt-guide -Launch"

🚀 Déjà installé ?

claude "/data-dbt-guide"

Ou tapez /data-dbt-guide dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

dbtdata build tooldbt modeldbt testtransformation de données dbt

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/data-dbt-guide ~/.claude/skills/

Payload du plugin : skills/data-dbt-guide · source éditable : data-skills/dbt-guide

📖 Manuel

Guide dbt

Workflow

1. Initialiser et structurer le projet

dbt init mon_projet        # crée le squelette
cd mon_projet
dbt debug                  # vérifie la connexion au warehouse

Arborescence cible :

models/
  staging/         ← nettoyage source, renommage, cast ; materialisation = view
  intermediate/    ← jointures, logique métier complexe ; materialisation = view ou ephemeral
  marts/           ← modèles finaux consommables ; materialisation = table
macros/
tests/
seeds/
snapshots/

dbt_project.yml — materialisations par dossier :

models:
  mon_projet:
    staging:
      +materialized: view
      +schema: staging
    intermediate:
      +materialized: view
    marts:
      +materialized: table
      +schema: marts

2. Déclarer les sources

# models/staging/sources.yml
version: 2
sources:
  - name: raw_crm
    schema: raw
    freshness:
      warn_after: {count: 12, period: hour}
      error_after: {count: 24, period: hour}
    loaded_at_field: _loaded_at
    tables:
      - name: orders
        description: "Commandes brutes issues du CRM"
        columns:
          - name: order_id
            tests: [unique, not_null]

Référencer dans un modèle :

select * from {{ source('raw_crm', 'orders') }}

Tester la fraîcheur :

dbt source freshness

3. Développer les modèles

Staging — un modèle par table source, préfixe stg_ :

-- models/staging/stg_orders.sql
with source as (
    select * from {{ source('raw_crm', 'orders') }}
),
renamed as (
    select
        order_id::varchar      as order_id,
        customer_id::int       as customer_id,
        created_at::timestamp  as created_at,
        status::varchar        as status
    from source
)
select * from renamed

Mart — utilise ref() pour chaque dépendance :

-- models/marts/fct_orders.sql
with orders as (
    select * from {{ ref('stg_orders') }}
),
customers as (
    select * from {{ ref('stg_customers') }}
)
select
    o.order_id,
    o.created_at,
    c.customer_name,
    o.status
from orders o
left join customers c on o.customer_id = c.customer_id

Critères de choix de materialisation :

CasMaterialisation recommandée
Nettoyage léger / peu consomméview
Rapport BI / dashboardtable
Table > 10M lignes avec clé temporelleincremental
Sous-requête intermédiaire réutiliséeephemeral
Suivi de changements type SCD2snapshot

Modèle incrémental :

-- models/marts/fct_events.sql
{{ config(materialized='incremental', unique_key='event_id') }}

select * from {{ ref('stg_events') }}

{% if is_incremental() %}
  where event_at > (select max(event_at) from {{ this }})
{% endif %}

4. Tester les données

Fichier YAML associé à chaque modèle :

# models/marts/fct_orders.yml
version: 2
models:
  - name: fct_orders
    description: "Faits commandes enrichis"
    columns:
      - name: order_id
        tests: [unique, not_null]
      - name: status
        tests:
          - accepted_values:
              values: ['pending', 'confirmed', 'shipped', 'cancelled']
      - name: customer_id
        tests:
          - relationships:
              to: ref('stg_customers')
              field: customer_id

Test custom SQL dans tests/ :

-- tests/assert_no_negative_amount.sql
select order_id
from {{ ref('fct_orders') }}
where amount < 0

Commandes :

dbt test                          # tous les tests
dbt test --select fct_orders      # tests d'un modèle
dbt test --store-failures         # stocker les lignes en erreur dans le warehouse

5. Créer des macros

-- macros/generate_surrogate_key.sql
{% macro generate_surrogate_key(fields) %}
    {{ dbt_utils.generate_surrogate_key(fields) }}
{% endmacro %}

-- macros/audit_columns.sql
{% macro audit_columns() %}
    current_timestamp as dbt_loaded_at,
    '{{ invocation_id }}' as dbt_run_id
{% endmacro %}

Usage dans un modèle :

select
    {{ generate_surrogate_key(['order_id', 'customer_id']) }} as sk_order,
    order_id,
    {{ audit_columns() }}
from {{ ref('stg_orders') }}

6. Documenter

models:
  - name: fct_orders
    description: >
      Faits commandes joints avec les clients.
      Utilisé par le dashboard Revenue dans Metabase.
    columns:
      - name: order_id
        description: "Identifiant unique de la commande (source CRM)"
dbt docs generate   # génère catalog.json
dbt docs serve      # ouvre le site sur localhost:8080

7. CI/CD et environnements

profiles.yml — deux targets :

mon_projet:
  target: dev
  outputs:
    dev:
      type: snowflake
      schema: "dbt_{{ env_var('DBT_USER', 'dev') }}"
      ...
    prod:
      type: snowflake
      schema: marts
      ...

Pipeline CI (GitHub Actions) :

- run: dbt build --target prod --select state:modified+  # uniquement les modèles modifiés et leurs dépendants
- run: dbt test  --target prod --select state:modified+
dbt build           # compile + run + test en une commande
dbt build --select +fct_orders   # modèle + tous ses ancêtres
dbt run --exclude tag:slow       # exclure les modèles lourds

Anti-patterns / Pièges

PiègeCorrection
select * en mart sans liste expliciteLister les colonnes exposées, ça évite les régressions silencieuses
Table en dur dans un modèle SQLToujours {{ ref() }} ou {{ source() }}
Pas de unique_key sur un incrémentalCrée des doublons à chaque run ; définir unique_key obligatoirement
Tests YAML uniquement sur la PKTester aussi les FK (relationships), les valeurs acceptées et les colonnes NOT NULL métier
Incrémental sans stratégie full refreshAjouter +full_refresh: false en dev seulement ; prévoir dbt run --full-refresh planifié
Modèles staging qui joinent plusieurs sourcesUn modèle staging = une source ; les jointures vont en intermediate/
Documentation rédigée après-coupÉcrire description + tests en même temps que le modèle, sinon jamais fait
dbt run en prod sans dbt testUtiliser dbt build qui enchaîne les deux et stoppe à la première erreur

Bonnes pratiques 2026

```yaml unit_tests:

model: fct_orders given:

rows: [{order_id: 1, amount: 100}, {order_id: 2, amount: 0}] expect: rows: [{order_id: 1, total: 100}] ```