Que fait Construction de modèles dbt ?
Quand l'utiliser
- Lors de la création ou du refactoring de modèles
.sqldans un projet dbt. - Pour choisir la matérialisation (vue / table / incrémental / éphémère).
- Pour structurer les couches (staging → intermediate → marts).
- Pour écrire des modèles incrémentaux pour des grandes tables en croissance.
- Ne PAS utiliser pour la rédaction de tests (utiliser
testing-dbt-projects) ni pour les échecs d'exécution (utiliserdebugging-dbt-runs).
Flux de travail
- [ ] Placer le modèle dans la bonne couche (staging/intermediate/marts)
- [ ] Référencer les modèles en amont uniquement via ref()/source() — jamais de noms en dur
- [ ] Choisir la matérialisation selon la taille et les besoins de rafraîchissement
- [ ] Pour l'incrémental, définir unique_key + filtre is_incremental()
- [ ] Ajouter une entrée schema.yml avec des tests
- Couche.
staging/= un modèle par table source, renommage/typage léger, matérialisé en vues.intermediate/= logique métier réutilisable.marts/= modèles dimensionnels finaux consommés par la BI, matérialisés en tables. - Référencer correctement. Utilisez
{{ ref('stg_orders') }}et{{ source('shop', 'orders') }}pour que dbt construise le DAG et gère les environnements. N'écrivez jamais de schema.table en dur. - Choisir la matérialisation : vue (peu coûteuse, toujours fraîche, petite), table (lectures rapides, reconstruite à chaque exécution), incrémental (grandes tables d'ajout/mise à jour), éphémère (CTE intégré, sans objet).
- Les modèles incrémentaux ne traitent que les lignes nouvelles ou modifiées.
Modèles
Modèle de staging — un par source, léger et cohérent :
-- models/staging/shop/stg_orders.sql
with source as (select * from {{ source('shop', 'orders') }})
select
order_id,
customer_id,
cast(order_ts as timestamp) as ordered_at,
round(amount_cents / 100.0, 2) as amount
from source
Modèle incrémental — filtrer les nouvelles lignes et définir une clé de fusion idempotente :
{{ config(materialized='incremental', unique_key='order_id',
incremental_strategy='merge') }}
select * from {{ ref('stg_orders') }}
{% if is_incremental() %}
-- uniquement les lignes plus récentes que ce qui a déjà été chargé, avec une fenêtre de rattrapage pour les données tardives
where ordered_at >= (select coalesce(max(ordered_at), '1900-01-01') from {{ this }})
- interval '3 jours'
{% endif %}
Le unique_key + merge rend les ré-exécutions idempotentes ; la fenêtre de rattrapage capture
les lignes arrivant en retard. Sur BigQuery/Spark, préférez insert_overwrite sur une partition de date.
Pièges courants
- Noms de tables en dur au lieu de
ref()/source()— casse le DAG, la lignée et le changement d'environnement. - Incrémental sans
unique_key— les ré-exécutions ajoutent des doublons. - Filtre incrémental
max(id)sans fenêtre de rattrapage — perd silencieusement les données tardives. - Logique métier dans le staging — gardez le staging léger ; les jointures/agrégations appartiennent à intermediate/marts.
- Tout matérialisé en
table— gaspille du temps d'entrepôt ; utilisez des vues pour les modèles petits/peu coûteux et l'incrémental pour les grands. - Un modèle géant — divisez en étapes intermédiaires pour la testabilité et la réutilisation.