🧱 Gérer plusieurs tables similaires avec dbt : une approche pilotée par configuration
Lorsqu’on doit maintenir plusieurs tables similaires dans un projet dbt — par exemple des exports quotidiens filtrés par pays ou région — il devient vite difficile et répétitif de créer et maintenir un fichier .sql par table.
La meilleure stratégie consiste à adopter une approche pilotée par configuration, en définissant les variations dans le fichier dbt_project.yml et en automatisant la génération des modèles grâce à une macro Jinja avec run-operation. Cette méthode apporte modularité, scalabilité, et maintenabilité.
🎯 Problématique
Vous avez besoin de générer des tables comme :
export_clients_fr→ clients en Franceexport_clients_us→ clients aux États-Unisexport_clients_ca→ clients au Canada
Chacune a :
- des conditions de filtre différentes
- parfois un type de matérialisation différent (table, incremental, etc.)
✅ Solution : génération dynamique de modèles via vars et run-operation
1. Centraliser les paramètres dans dbt_project.yml
vars:
export_tables:
- name: export_clients_fr
pays: FR
materialized: table
- name: export_clients_us
pays: US
materialized: incremental
- name: export_clients_ca
pays: CA
materialized: table
Ces variables définissent chaque modèle à générer : son nom, son filtre, et son comportement.
2. Créer une macro generate_exports.sql (dans macros/)
{% macro generate_exports() %}
{% for table in var('export_tables') %}
{% set model_content %}
{{ '{{ config(materialized="' ~ table.materialized ~ '") }}' }}
SELECT *
FROM {{ '{{ ref("stg_clients") }}' }}
WHERE pays = '{{ table.pays }}'
{% endset %}
{% do write_file("models/generated_exports/" ~ table.name ~ ".sql", model_content) %}
{% endfor %}
{% endmacro %}
Cette macro va générer un fichier .sql distinct pour chaque table définie dans la config.
3. Exécuter la macro pour créer les fichiers
dbt run-operation generate_exports
➡️ Cela crée des fichiers .sql dans models/generated_exports/ comme :
export_clients_fr.sqlexport_clients_us.sqlexport_clients_ca.sql
4. Exécuter les modèles générés
dbt run --select path:models/generated_exports/
Chaque modèle sera traité comme un fichier classique par dbt, avec ses propres filtres et stratégie de matérialisation.
🧠 Avantages de cette approche
| Avantage | Détail |
|---|---|
| 🧩 Modulaire | Une seule logique de génération partagée |
| ⚙️ Paramétrable | Filtre, stratégie (table, incremental, etc.) centralisés |
| 🔁 Scalable | Ajout de nouveaux cas = une ligne dans dbt_project.yml |
| 🧪 Testable | Tous les modèles générés peuvent hériter des mêmes tests ou documentations |
| 📦 Git-friendly | Les règles métiers et paramètres sont versionnés avec le code |
| ⏱️ Compatible incrémental | Chaque modèle peut activer l’incrémentalité si besoin (unique_key, strategy) |
⚠️ Ce qui n’est pas possible dans dbt
Il n’est pas possible d’avoir un seul fichier
.sqldans/models/qui génère plusieurs modèles différents via une bouclefor.
dbt exécute chaque fichier .sql en un unique modèle.
Une boucle for dans un fichier .sql écraserait les configs et ne génèrerait qu’un seul objet.
✅ Conclusion
Utiliser une approche config-driven + macro + run-operation est la solution la plus robuste pour générer plusieurs modèles similaires dans dbt.
Elle offre à la fois souplesse, automatisation, et clarté, tout en conservant la puissance de dbt (incremental, test, documentation, lineage…).