Pourquoi dbt-core est devenu incontournable
Avant dbt, transformer des données dans un entrepôt se faisait avec un patchwork ingérable : scripts SQL exécutés en cron, vues PostgreSQL empilées, procédures stockées non versionnées, fichiers Excel envoyés par email. Personne ne savait quel script avait modifié quelle table, ni comment recalculer un KPI mensuel sans casser la production. La donnée était fragile, opaque et impossible à auditer.
dbt (data build tool) a renversé la table en proposant une discipline simple : tu écris ton SQL dans des fichiers .sql versionnés Git, dbt en gère les dépendances automatiquement ({{ ref('table_amont') }}), génère les CREATE TABLE ou CREATE VIEW, exécute des tests de qualité (unicité, non-nullité, valeurs autorisées), et produit une documentation HTML interactive avec graphe de lignage. Tout ça en quelques minutes par jour de configuration.
Le résultat pour une PME francophone d’Afrique de l’Ouest : tes 50 requêtes SQL éparses deviennent un projet d’analytique versionné que ton équipe peut comprendre, tester et faire évoluer sans peur de tout casser. Plus de scripts perdus, plus de KPI qui changent silencieusement, plus de bug découvert en réunion comité de direction.
Ce tutoriel s’inscrit dans le guide général Data engineering self-hosted 2026. Tu vas y apprendre à installer dbt-core dans un environnement Python, structurer un projet en couches staging/intermediate/mart, écrire des tests, générer la documentation HTML et orchestrer les exécutions.
Prérequis
- VPS Hetzner Cloud CX22 minimum (2 700 F CFA/mois). Plus si ton entrepôt est sur le même VPS.
- Ubuntu 22.04 LTS ou 24.04 LTS.
- Python 3.10 à 3.12 installé.
- Un entrepôt de données accessible : PostgreSQL (recommandé pour ce tutoriel), DuckDB, Snowflake, BigQuery, ClickHouse ou autre adaptateur supporté.
- Compétences SQL solides (CTE, window functions, joins).
- Git installé et un compte GitHub/GitLab pour versionner le projet.
La philosophie dbt en 3 principes
Avant d’installer quoi que ce soit, intériorise les 3 principes qui font la force de dbt et qui doivent guider toutes tes décisions de modélisation :
- SQL only — pas de Python, pas de Spark, pas de Pandas. Si ton entrepôt sait l’exécuter en SQL, dbt le fait. Cette contrainte force la simplicité et garantit que tout reste exécutable directement dans la base.
- Modularité par modèle — chaque fichier
.sqlproduit une seule table ou vue. Les transformations complexes sont décomposées en plusieurs modèles successifs, chacun référencé par{{ ref('autre_modele') }}. dbt construit le DAG de dépendances et exécute dans le bon ordre. - Tests systématiques — chaque modèle critique a au moins 3 tests : unicité de la clé primaire, non-nullité des colonnes obligatoires, intégrité référentielle vers les tables amont. C’est ton filet de sécurité contre les régressions silencieuses.
Ces principes paraissent simples mais ils transforment radicalement la qualité de tes pipelines de données. Une équipe data qui les respecte stricte gagne typiquement 50 à 70 % de temps sur le débogage et l’onboarding de nouveaux collaborateurs.
Installation pas-à-pas
# Sur le VPS, créer l'environnement projet
mkdir -p ~/dbt-pme && cd ~/dbt-pme
python3.12 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
# Installer dbt-core et l'adaptateur PostgreSQL
pip install dbt-core dbt-postgres
# Vérifier
dbt --version
Tu dois voir dbt-core 1.8.x et dbt-postgres 1.8.x. Si tu vises un autre entrepôt, remplace par dbt-duckdb, dbt-snowflake, dbt-bigquery, dbt-clickhouse selon ton cas.
Initialiser un projet dbt
dbt init pme_analytics
# Réponds aux questions :
# - database: postgres
# - host: localhost
# - port: 5432
# - user: dbtuser
# - password: ***
# - dbname: warehouse
# - schema: dbt_dev
# - threads: 4
cd pme_analytics
dbt debug # Vérifie la connexion
La commande dbt debug teste la connexion à ton entrepôt et signale les permissions manquantes. Corrige avant d’aller plus loin.
Structurer son projet en 3 couches
La pratique recommandée par la communauté dbt est de séparer ton projet en trois couches distinctes, chacune avec une responsabilité claire :
Couche staging
Une vue par source brute. Renommage des colonnes, conversion des types, suppression des PII non nécessaires. Aucune business logic. Les fichiers vivent dans models/staging/<source>/stg_<source>__<table>.sql.
-- models/staging/woocommerce/stg_woocommerce__commandes.sql
SELECT
id::bigint AS commande_id,
customer_id::bigint AS client_id,
status AS statut_commande,
date_created::timestamp AS date_creation,
total::numeric(12,2) AS montant_fcfa,
payment_method AS methode_paiement
FROM {{ source('woocommerce_raw', 'wp_wc_orders') }}
WHERE date_created >= '2024-01-01'
Couche intermediate
Modèles intermédiaires qui combinent plusieurs staging pour préparer les calculs métier. Pas exposés directement aux utilisateurs finaux. Les fichiers vivent dans models/intermediate/int_<sujet>.sql.
-- models/intermediate/int_commandes_enrichies.sql
SELECT
c.commande_id,
c.client_id,
c.date_creation,
c.montant_fcfa,
c.methode_paiement,
cl.nom_complet AS client_nom,
cl.ville AS client_ville,
cl.pays AS client_pays
FROM {{ ref('stg_woocommerce__commandes') }} c
LEFT JOIN {{ ref('stg_woocommerce__clients') }} cl
ON c.client_id = cl.client_id
Couche mart
Tables finales exposées aux dashboards Metabase, Grafana ou aux exports. Une table par sujet métier. Les fichiers vivent dans models/marts/<domaine>/<table>.sql.
-- models/marts/ventes/fct_ventes_quotidiennes.sql
{{ config(materialized='table') }}
SELECT
DATE_TRUNC('day', date_creation) AS jour,
client_pays,
methode_paiement,
COUNT(*) AS nb_commandes,
SUM(montant_fcfa) AS ca_total_fcfa,
AVG(montant_fcfa) AS panier_moyen
FROM {{ ref('int_commandes_enrichies') }}
WHERE statut_commande IN ('completed', 'processing')
GROUP BY 1, 2, 3
Choisir la bonne matérialisation
dbt offre 4 stratégies de matérialisation pour chaque modèle. Le choix a un impact massif sur les performances et le coût :
- view — défaut, pas de stockage, recalculé à chaque requête. Bon pour staging et intermediate.
- table — recrée la table à chaque
dbt run. Bon pour les marts qui doivent répondre rapidement. - incremental — n’insère que les nouvelles lignes depuis la dernière exécution. Indispensable pour les fact tables qui grossissent (millions de lignes).
- ephemeral — pas de matérialisation, le SQL est inliné comme CTE dans les modèles aval. Bon pour les transformations simples utilisées une seule fois.
Règle pratique : staging en view, intermediate en view ou ephemeral, marts en table pour les petits, incremental pour les gros (>1M lignes).
Tests génériques et singuliers
dbt distingue deux catégories de tests. Les tests génériques sont déclaratifs dans un fichier YAML et s’appliquent à n’importe quelle colonne :
# models/staging/woocommerce/_woocommerce__models.yml
version: 2
models:
- name: stg_woocommerce__commandes
columns:
- name: commande_id
tests:
- unique
- not_null
- name: client_id
tests:
- relationships:
to: ref('stg_woocommerce__clients')
field: client_id
- name: statut_commande
tests:
- accepted_values:
values: ['pending', 'processing', 'completed', 'cancelled', 'refunded']
Les tests singuliers sont des requêtes SQL qui doivent retourner zéro ligne pour passer. Ils vivent dans tests/<nom>.sql :
-- tests/montants_negatifs.sql
SELECT commande_id, montant_fcfa
FROM {{ ref('stg_woocommerce__commandes') }}
WHERE montant_fcfa < 0
Lance tous les tests avec dbt test. Échec = pipeline bloqué = problème de qualité de données qui ne polluera pas tes dashboards.
Génération de la documentation HTML
L’une des fonctionnalités les plus précieuses de dbt est la documentation auto-générée. Tu décris chaque modèle et chaque colonne dans les fichiers YAML, dbt produit un site HTML statique avec recherche, graphe de lignage et descriptions :
dbt docs generate
dbt docs serve --port 8080
Tu obtiens un site web interactif sur http://ton-vps:8080 qui montre toutes tes tables, leurs colonnes, leurs dépendances, et leurs tests. Pour une équipe à Dakar, Abidjan ou Bamako où plusieurs personnes manipulent les données sans expertise data engineering, c’est le meilleur outil d’onboarding qui soit.
Orchestration : exécuter dbt automatiquement
dbt en lui-même n’est pas un orchestrateur. Pour exécuter dbt run et dbt test automatiquement, plusieurs options :
- Cron — solution la plus simple, un fichier
/etc/cron.d/dbtqui lance les commandes à heure fixe. OK pour 1-2 exécutions par jour. - Dagster — orchestrateur moderne, intègre nativement dbt. Voir notre tutoriel Dagster self-hosted.
- GitHub Actions — exécute dbt sur chaque push, idéal pour CI/CD.
- Airflow — historique, lourd, à réserver aux équipes ayant déjà l’expertise.
Adaptation au contexte ouest-africain
dbt-core répond particulièrement bien aux contraintes des PME francophones. Premièrement, le coût zéro de la licence : alors que dbt Cloud démarre à 100 USD/mois par développeur, dbt-core est entièrement gratuit. Pour une équipe data de 3 à 5 personnes à Dakar ou Abidjan, l’économie annuelle dépasse 3 millions F CFA.
Deuxièmement, la gouvernance documentée. Les obligations réglementaires sectorielles (BCEAO pour les fintech, CIMA pour l’assurance, OHADA pour le commercial) imposent de plus en plus de prouver la traçabilité des KPI consolidés. Un projet dbt versionné Git avec tests et documentation auto-générée est la preuve par excellence.
Troisièmement, la portabilité multi-entrepôts. Tu démarres avec PostgreSQL sur Hetzner pour limiter les coûts. Quand ton volume explose, tu migres vers DuckDB pour l’analytique, ou Snowflake si ton CFO veut une solution managée. Tes modèles dbt restent les mêmes, seul le profile change.
Erreurs fréquentes à éviter
- Tout matérialiser en table — gaspille du stockage et ralentit. Garde staging en view.
- Oublier les tests dès le début — ajoute au minimum unique + not_null sur chaque clé primaire dès la création du modèle.
- Sauter la couche staging — la tentation est forte d’aller direct des sources aux marts. Ne le fais pas. La couche staging est ton rempart contre les changements de schéma amont.
- Modèles trop longs — un fichier de 200 lignes de SQL est ingérable. Découpe en intermediate.
- Pas de documentation — une colonne
montantsans description, c’est ouvrir la porte aux interprétations divergentes (HT ? TTC ? F CFA ? EUR ?). - Versions Git négligées — pousse à chaque modification, branche feature pour les évolutions majeures.
Trois cas d’usage concrets
- Marketplace à Dakar — 80 modèles dbt sur PostgreSQL, exécutés toutes les heures par cron. Couvre vendeurs, produits, commandes, paiements, livraisons, retours. Documentation HTML servie aux équipes commerciales et finance. Économie : 8 millions F CFA/an vs solution managée équivalente.
- Microfinance à Abidjan — 30 modèles dbt sur Snowflake, déclenchés par Dagster après les syncs Airbyte. Calcul des indicateurs réglementaires BCEAO, taux de défaut, encours par agence. Tests stricts (unicité, intégrité référentielle, cohérence montants). Audit annuel facilité.
- SaaS RH à Ouagadougou — 15 modèles dbt sur DuckDB hébergé sur Hetzner CX22. Calcul des fiches de paie, congés, primes. Tests singuliers vérifient qu’aucun salaire négatif n’est jamais produit.
Checklist post-déploiement
- ✅ dbt-core et adaptateur installés,
dbt debugOK - ✅ Projet structuré en 3 couches (staging, intermediate, marts)
- ✅ Au moins 5 modèles fonctionnels avec
{{ ref() }}et{{ source() }} - ✅ Tests génériques sur toutes les clés primaires
- ✅ Au moins 1 test singulier métier
- ✅ Documentation HTML générée et accessible à l’équipe
- ✅ Projet versionné dans Git, branches feature pour les évolutions
- ✅ Orchestration en place (cron minimal, Dagster idéal)
- ✅ Notifications d’échec de pipeline vers Slack/Mattermost
- ✅ Documentation interne : qui peut modifier quels modèles
FAQ
dbt-core vs dbt Cloud ?
dbt-core est gratuit et self-hosted, parfait pour PME. dbt Cloud ajoute IDE web, scheduler, monitoring managés à 100 USD+/mois/dev. Justifié uniquement si pas d’équipe DevOps.
Quel adaptateur choisir ?
PostgreSQL pour démarrer (gratuit, simple). DuckDB pour analytique pure (rapide, embarqué). BigQuery/Snowflake si déjà investi dans l’écosystème cloud.
Combien de temps pour migrer mes scripts SQL existants vers dbt ?
Compte 2 à 5 jours pour un projet de 30 scripts. La courbe d’apprentissage est rapide pour qui maîtrise SQL.
dbt remplace-t-il un data engineer ?
Non, il rend leur travail 5× plus productif et leur permet de se concentrer sur la modélisation et la qualité plutôt que sur la plomberie.
Pour aller plus loin
- 📖 Guide général Data engineering self-hosted 2026
- 📥 Installer et configurer Airbyte OSS sur VPS Hetzner
- 🎯 Dagster self-hosted : orchestration moderne
- 🦆 DuckDB pour l’analytique Python sur VPS Hetzner
- 🌍 Documentation officielle dbt
Besoin d’aide pour structurer ton dbt ?
Tu as 50 scripts SQL éparpillés et tu veux enfin un projet versionné, testé, documenté ? ITSkillsCenter propose un audit gratuit de 30 minutes pour cadrer la migration. Contacte-nous via WhatsApp +221 78 226 83 77 ou demande directement ton audit gratuit en ligne.
[ITS] ITSkillsCenter — formations IT et conseil pour PME d’Afrique de l’Ouest. Dakar · Abidjan · Ouagadougou · Bamako · Conakry. Tous nos contenus sont audités selon notre charte éditoriale Ahl-Sunna.