Maitriser dbt en 2026 : Modelisation SQL, Tests de Qualite et Preparation aux Entretiens Data Analyst
Guide complet dbt pour data analysts : architecture staging/intermediate/marts, materialisations, tests de qualite des donnees, macros Jinja et questions d'entretien technique les plus posees en 2026.

Le paysage de la data analyse a profondement mute depuis l'avenement du paradigme ELT. Au coeur de cette transformation, dbt (data build tool) occupe desormais une place centrale dans la stack technique de la majorite des equipes data, des startups aux grands groupes. Avec dbt Core v2.0 en alpha et la version stable v1.12, le framework offre un ecosysteme complet pour transformer, tester et documenter les donnees directement dans l'entrepot, le tout gere par Git comme n'importe quel code applicatif.
La demande du marche reflate cette evolution : les fiches de poste de dbt data analyst mentionnent le framework parmi les competences requises dans une proportion croissante, et les entretiens techniques integrent systematiquement des dbt interview questions portant sur le dbt modeling, les strategies de materialisation et les tests de qualite. Cet article constitue un guide de reference couvrant data analytics dbt dans sa globalite, enrichi d'exemples concrets et des questions d'entretien les plus recurrentes en data analytics.
dbt intervient exclusivement sur la phase T (Transform) du pipeline ELT. Les donnees brutes sont d'abord chargees dans l'entrepot par des connecteurs d'ingestion comme Fivetran ou Airbyte, puis dbt se charge de les transformer en modeles exploitables, testes et documentes. L'ensemble des transformations s'execute nativement dans le moteur SQL de l'entrepot — BigQuery, Snowflake, Redshift ou PostgreSQL — sans necessiter d'infrastructure de calcul tierce.
Organisation du projet : les couches Staging, Intermediate et Marts
La robustesse d'un projet dbt repose avant tout sur la rigueur de son architecture. Le pattern recommande par la communaute et par dbt Labs s'articule autour de trois couches distinctes, chacune repondant a un objectif precis dans la chaine de transformation.
La couche staging constitue le point d'entree du projet. Chaque modele staging correspond a une table source unique et se limite a des operations de nettoyage elementaires : renommage de colonnes, conversion de types, filtrage des enregistrements manifestement invalides. Aucune jointure, aucune agregation ne doit apparaitre a ce niveau.
La couche intermediate rassemble la logique metier qui articule les modeles staging entre eux. Les jointures, les calculs derives et les filtres metier trouvent leur place dans ces modeles, qui servent de composants reutilisables pour la couche superieure.
La couche marts produit les modeles finaux destines aux consommateurs de donnees : tableaux de bord, rapports automatises, requetes ad hoc des analystes. Chaque mart represente un concept metier identifiable — une table de faits transactionnelles, une dimension client, un indicateur de performance.
Le modele staging ci-dessous illustre le traitement d'une table de paiements provenant de Stripe. Les colonnes sont renommees selon les conventions du projet, les montants convertis de centimes en dollars, et les paiements en echec exclus des le depart.
-- models/staging/stripe/stg_stripe__payments.sql
with source as (
select * from {{ source('stripe', 'payments') }}
),
renamed as (
select
id as payment_id,
amount / 100.0 as amount_usd, -- Stripe stores cents
status as payment_status,
created::timestamp as created_at,
customer_id
from source
where status != 'failed' -- Filter invalid records early
)
select * from renamedLe modele mart suivant exploite ce staging pour construire un indicateur de chiffre d'affaires mensuel net. L'agregation par mois, le decompte des transactions et le calcul des remboursements produisent un modele directement consommable par l'equipe finance.
-- models/marts/finance/fct_monthly_revenue.sql
with payments as (
select * from {{ ref('stg_stripe__payments') }}
),
monthly as (
select
date_trunc('month', created_at) as revenue_month,
count(*) as total_transactions,
sum(amount_usd) as gross_revenue,
sum(case when payment_status = 'refunded' then amount_usd else 0 end) as refunds
from payments
group by 1
)
select
revenue_month,
total_transactions,
gross_revenue,
refunds,
gross_revenue - refunds as net_revenue -- Key business metric
from monthlyL'interet fondamental de cette separation en couches reside dans l'isolation des changements. Lorsqu'un schema source evolue — une colonne renommee, un champ ajoute par le fournisseur — seul le modele staging correspondant necessite une mise a jour. Les dizaines de modeles en aval continuent de fonctionner sans modification, car ils referencent d'autres modeles via ref() et non des tables en dur.
Materialisations : adapter la persistance au cas d'usage
Le choix de la materialisation determine la facon dont dbt persiste chaque modele dans l'entrepot. Ce choix impacte directement les performances de requetage, les couts de calcul et la fraicheur des donnees. Quatre materialisations couvrent l'ensemble des besoins courants.
| Materialization | Use Case | Rebuild Behavior |
|----------------|----------|-------------------|
| view | Lightweight staging models, low query frequency | Recreated as SQL view on each run |
| table | Mart models queried often by dashboards | Full table rebuild on each run |
| incremental | Large fact tables (events, logs) | Appends/merges new rows only |
| ephemeral | Reusable CTEs, never queried directly | Compiled inline as subquery |
La materialisation view convient aux modeles staging peu sollicites : le cout de creation est negligeable, mais chaque requete reevalue le SQL sous-jacent. La materialisation table inverse ce compromis en precalculant les resultats au prix d'un rebuild complet a chaque execution de dbt run. Pour les marts frequemment interroges par des dashboards, ce choix offre des temps de reponse optimaux.
La materialisation incremental merite une attention approfondie, car elle repond au probleme le plus courant en production : le traitement de tables de faits contenant des centaines de millions de lignes.
-- models/marts/product/fct_page_views.sql
{{ config(
materialized='incremental',
unique_key='page_view_id',
incremental_strategy='merge'
) }}
with events as (
select
event_id as page_view_id,
user_id,
page_url,
session_id,
event_timestamp
from {{ ref('stg_snowplow__events') }}
where event_type = 'page_view'
{% if is_incremental() %}
-- Only process new events since last run
and event_timestamp > (select max(event_timestamp) from {{ this }})
{% endif %}
)
select * from eventsLe fonctionnement repose sur la macro is_incremental(), qui detecte si le modele cible existe deja dans l'entrepot. Lors de la premiere execution, l'integralite des donnees est traitee. Lors des executions suivantes, seuls les evenements posterieurs au dernier timestamp enregistre sont charges. Un pipeline qui prenait deux heures en reconstruction complete peut ainsi se reduire a quelques minutes. La strategie merge assure en outre que les enregistrements deja presents sont mis a jour si leur cle unique correspond, evitant toute duplication.
Tester la qualite des donnees : schema tests et tests singuliers
La fiabilite d'un projet dbt en production repose sur la rigueur de sa couverture de tests. dbt propose deux mecanismes complementaires : les tests de schema, declares en YAML et couvrant les contraintes d'integrite classiques, et les tests singuliers, ecrits en SQL pour valider des regles metier specifiques. L'execution de dbt test declenche l'ensemble des verifications et fait echouer le pipeline en cas de violation.
Les tests de schema se declarent dans les fichiers YAML de documentation des modeles. Cette approche declarative couvre la grande majorite des controles de qualite courants sans necessiter l'ecriture de SQL supplementaire.
# models/staging/stripe/_stripe__models.yml
version: 2
models:
- name: stg_stripe__payments
description: "Cleaned payment records from Stripe"
columns:
- name: payment_id
description: "Unique payment identifier"
tests:
- unique
- not_null
- name: payment_status
tests:
- accepted_values:
values: ['succeeded', 'pending', 'refunded']
- name: amount_usd
tests:
- not_null
- dbt_utils.expression_is_true:
expression: ">= 0" # No negative paymentsLes tests unique et not_null garantissent l'integrite de la cle primaire. Le test accepted_values verifie que le statut de paiement appartient a un ensemble maitrise de valeurs — toute nouvelle valeur inattendue declenchera une alerte. Le test dbt_utils.expression_is_true, provenant du package dbt-utils, valide qu'aucun montant n'est negatif.
Pour les regles metier complexes que le YAML ne peut exprimer, les tests singuliers offrent la flexibilite du SQL pur. Un test singulier est un fichier SQL place dans le repertoire tests/ : toute ligne retournee par la requete constitue un echec.
-- tests/assert_revenue_not_negative.sql
-- This test fails if any month has negative net revenue
select
revenue_month,
net_revenue
from {{ ref('fct_monthly_revenue') }}
where net_revenue < 0 -- Should never happenCe test capture un invariant metier fondamental : le revenu net mensuel ne doit jamais etre negatif. Si une corruption de donnees en amont ou une erreur de logique produisait un tel resultat, le pipeline s'interromprait avant que le chiffre errone n'apparaisse dans les rapports de direction. L'integration de dbt test dans le pipeline CI/CD constitue ainsi un filet de securite indispensable pour tout projet en production.
Prêt à réussir tes entretiens Data Analytics ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Jinja et macros : factoriser la logique SQL
La puissance de dbt depasse le simple SQL grace au moteur de templates Jinja. Les deux fonctions essentielles — ref() pour referencer un modele et source() pour pointer vers une table brute — construisent le DAG (graphe oriente acyclique) qui orchestre l'ordre d'execution. Au-dela de ces fonctions natives, les macros personnalisees permettent de factoriser toute logique SQL repetitive en composants reutilisables.
La macro suivante centralise la conversion de centimes en dollars, une operation recurrente dans tout projet manipulant des donnees Stripe ou des montants monetaires stockes en centimes.
-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name) %}
({{ column_name }} / 100.0)::numeric(12, 2)
{% endmacro %}Une fois definie, cette macro s'utilise dans n'importe quel modele du projet, garantissant une logique de conversion strictement identique partout.
-- Usage in any model
select
payment_id,
{{ cents_to_dollars('amount_cents') }} as amount_usd,
{{ cents_to_dollars('tax_cents') }} as tax_usd
from {{ source('stripe', 'payments') }}Au moment du build, Jinja compile la macro en SQL standard. La valeur ajoutee est double : d'une part, la coherence est garantie — modifier la precision decimale ou la formule de conversion ne necessite qu'un changement unique dans le fichier macro. D'autre part, les macros constituent un outil de standardisation au sein des equipes, centralisant les conventions de transformation et reduisant les risques d'incoherence entre analystes travaillant sur le meme projet.
Questions d'entretien dbt : les incontournables
Les processus de recrutement en data analytics et data engineering evaluent les competences dbt a travers des questions axees sur la comprehension operationnelle du framework. Les reponses attendues privilegient le raisonnement et la mise en contexte plutot que la restitution de definitions.
Q1 : Quelle distinction fondamentale existe entre ref() et source() ?
La fonction source() designe une table brute chargee par un outil d'ingestion et declaree dans un fichier sources.yml. La fonction ref() designe un modele dbt existant dans le projet. Au-dela de cette distinction de cible, ref() joue un role structurel determinant : chaque appel a ref() enregistre une dependance dans le DAG, permettant a dbt de determiner l'ordre d'execution correct et de tracer la lineage complete des donnees. Remplacer ref() par un nom de table en dur rompt cette chaine de dependances et produit des erreurs silencieuses lorsque l'ordre d'execution change.
Q2 : Dans quels cas la materialisation incrementale est-elle justifiee ?
La materialisation incrementale se justifie lorsque trois conditions sont reunies : les donnees source suivent un schema d'ajout chronologique (append-only) ou disposent d'une colonne de timestamp fiable, le volume de la table rend la reconstruction complete couteuse en temps ou en ressources, et la logique de transformation est suffisamment simple pour etre appliquee de maniere incrementale. Les tables d'evenements analytiques, les journaux applicatifs et les series temporelles constituent les candidats ideaux. Les tables de dimensions de petite taille ne beneficient pas de cette approche, car la complexite additionnelle (gestion des arrivees tardives, strategie de deduplication) l'emporte sur le gain de performance.
Q3 : Comment dbt implemente-t-il le suivi des dimensions a evolution lente (SCD Type 2) ?
Les snapshots dbt implementent nativement le tracking SCD Type 2. Un snapshot surveille une table source a intervalles reguliers et enregistre chaque modification detectee en ajoutant des colonnes dbt_valid_from et dbt_valid_to. Deux strategies de detection sont disponibles : la strategie timestamp, qui compare une colonne updated_at, et la strategie check, qui compare directement les valeurs de colonnes specifiees. Les snapshots s'executent via la commande dediee dbt snapshot, distincte de dbt run, car ils capturent un etat historique qui ne doit pas etre confondu avec les transformations regulieres.
Q4 : Quel est l'objectif du decoupage staging/intermediate/marts ?
Ce decoupage en couches attribue une responsabilite unique a chaque niveau. Le staging nettoie et normalise les donnees brutes — un modele par table source, sans logique metier. Les modeles intermediate assemblent ces briques pour construire des entites metier intermediaires via des jointures et des calculs. Les marts produisent les sorties finales directement consommables. Ce pattern isole les impacts des changements : une evolution de schema source ne touche que le staging correspondant, sans propagation aux couches superieures. La regle cardinale : un modele mart ne doit jamais appeler source() directement, uniquement des ref() vers d'autres modeles.
Q5 : Comment distinguer tests de schema, tests singuliers et tests generiques ?
Les tests de schema sont des verifications declaratives en YAML appliquees aux colonnes : unique, not_null, accepted_values, relationships. Les tests singuliers sont des requetes SQL autonomes stockees dans tests/ — toute ligne retournee signale un echec. Les tests generiques sont des macros parametrables qui etendent le catalogue de tests schema : une fois definis, ils s'utilisent en YAML exactement comme les tests natifs. La strategie recommandee : les tests de schema pour les contraintes d'integrite, les tests singuliers pour les invariants metier complexes ("le revenu net ne diminue jamais de plus de 50 % d'un mois sur l'autre"), et les tests generiques pour les validations recurrentes specifiques au domaine.
Bonnes pratiques pour un projet dbt robuste
Un projet dbt qui depasse quelques dizaines de modeles exige des conventions strictes pour rester maintenable. Les pratiques suivantes, eprouvees sur des projets comptant plusieurs centaines de modeles, constituent un socle de reference.
Conventions de nommage systematiques. Les modeles staging portent le prefixe stg_, les modeles intermediate le prefixe int_, les tables de faits fct_ et les dimensions dim_. L'arborescence des fichiers suit la source des donnees : models/staging/stripe/, models/staging/salesforce/. Cette convention permet a tout membre de l'equipe de localiser instantanement un modele sans consulter de documentation.
Documentation au plus pres du code. Chaque modele et chaque colonne significative doivent disposer d'une description dans le fichier YAML de documentation associe. La commande dbt docs generate produit un site de documentation complet avec un DAG interactif — un outil precieux pour l'integration des nouveaux arrivants et l'audit de la lineage.
Controle de fraicheur des sources. Avant toute transformation, la verification de la fraicheur des donnees source detecte les defaillances d'ingestion en amont.
# models/staging/stripe/_stripe__sources.yml
version: 2
sources:
- name: stripe
database: raw
schema: stripe
freshness:
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}
loaded_at_field: _fivetran_synced
tables:
- name: payments
- name: customersLa commande dbt source freshness compare le timestamp du dernier enregistrement charge au seuil configure. Un retard de 24 heures sur les donnees de paiement Stripe indique une panne du connecteur d'ingestion — une information critique pour eviter de produire des rapports bases sur des donnees incompletes. Dans un pipeline de production, cette verification precede systematiquement l'execution de dbt run.
Pour developper les competences SQL mobilisees dans la redaction de modeles dbt, les guides sur les fonctions de fenetre SQL et les CTEs et le SQL avance pour entretiens couvrent les patterns de requetes les plus frequents dans les modeles staging et marts.
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
Conclusion
Les points fondamentaux a retenir pour tout data analyst souhaitant maitriser dbt en 2026 :
- dbt assure la transformation des donnees dans le paradigme ELT en executant du SQL directement dans l'entrepot, sans couche de calcul intermediaire
- L'architecture en couches staging/intermediate/marts isole le nettoyage des sources de la logique metier, rendant chaque modification previsible et localisee
- Le choix de la materialisation — view, table, incremental ou ephemeral — conditionne les performances et les couts ; les modeles incrementaux reduisent drastiquement le temps de traitement des tables volumineuses
- Les tests de schema declaratifs (YAML) couvrent les contraintes d'integrite courantes ; les tests singuliers (SQL) valident les invariants metier complexes ; l'integration dans le CI/CD empeche la propagation de donnees corrompues
- Les macros Jinja centralisent la logique SQL reutilisable et garantissent la coherence des transformations a l'echelle du projet
- Les controles de fraicheur des sources constituent la premiere ligne de defense contre les defaillances d'ingestion en amont
- La preparation aux entretiens techniques dbt doit privilegier la demonstration de raisonnement — compromis entre materialisations, construction du DAG, strategies de test — plutot que la restitution de definitions apprises par coeur
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
Tags
Partager
Articles similaires

SQL Avance pour Entretiens Data Analyst : Sous-requetes, Pivots et Optimisation des Requetes en 2026
Maitrisez le SQL avance pour les entretiens data analyst en 2026. Sous-requetes correlees, pivots par agregation conditionnelle, plans EXPLAIN ANALYZE et strategies d'indexation sur PostgreSQL 17 avec exemples concrets.

SQL pour les Data Analysts : fonctions de fenetrage, CTE et requetes avancees
Guide complet sur les fonctions de fenetrage SQL (window functions), les CTE et les requetes analytiques avancees. Syntaxe, exemples concrets et patterns utilises en entretien data analyst.

Top 25 des questions d'entretien en Data Analytics en 2026
Les 25 questions les plus fréquentes en entretien data analytics en 2026 : SQL, Python, Power BI, statistiques et questions comportementales avec des réponses détaillées et des exemples de code.