🎯 Objectif
Tu veux un seul projet dbt, mais que :
- chaque client (tenant) ait ses propres tables dans un schema dédié (
leclerc.,carrefour., etc.), - le même modèle dbt (
fact_ventes.sql) soit exécuté pour chaque tenant sans dupliquer le code.
✅ Solution : schemas dynamiques par tenant
dbt permet d’utiliser des schemas dynamiques à l’aide de la méthode generate_schema_name.
🧱 1. Définir les tenants dans dbt_project.yml
vars:
tenants: ["leclerc", "carrefour", "intermarche"]
🧠 2. Surcharge du comportement de dbt dans dbt_project.yml
Ajoute ceci pour personnaliser les noms de schemas générés :
models:
mon_projet:
+schema: "{{ target.schema }}_{{ var('current_tenant', 'default') }}"
Ex : si
target.schema = "analytics"etcurrent_tenant = "leclerc"⇒ les modèles seront dans le schémaanalytics_leclerc
⚙️ 3. Surcharge generate_schema_name (optionnel mais plus propre)
Dans macros/generate_schema_name.sql :
{% macro generate_schema_name(custom_schema_name, node) %}
{{ target.schema }}_{{ var('current_tenant', 'default') }}
{% endmacro %}
📄 4. Exemple de modèle unique exécuté pour tous les tenants
-- models/fact_ventes.sql
select
id_vente,
produit,
quantite,
prix
from {{ ref('stg_ventes') }}
🔁 5. Exécution multi-tenant avec script bash
for tenant in leclerc carrefour intermarche
do
dbt run --vars "{current_tenant: '$tenant'}"
done
✅ Cela exécute le même code, mais chaque fois avec un schéma différent (
analytics_leclerc,analytics_carrefour…)
🔎 6. Organisation des schémas dans ton entrepôt
Tu obtiendras dans BigQuery ou Snowflake ou Redshift :
analytics_leclerc.fact_ventes
analytics_carrefour.fact_ventes
analytics_intermarche.fact_ventes
👉 Ce qui t’apporte :
- isolation des données (chaque client a son propre espace)
- code unique (pas besoin de copier-coller
fact_ventes_leclerc.sql,fact_ventes_carrefour.sql…)
✅ Avantages
| Avantage | Détail |
|---|---|
| 🔁 Réutilisation du code | Un seul modèle fact_ventes.sql pour tous |
| 📁 Organisation claire | Chaque tenant a son propre schéma (analytics_leclerc) |
| 🛡️ Sécurité / isolation | Les données ne se mélangent pas (utile pour les ACLs ou droits d’accès) |
📦 Compatible avec ref() | Pas besoin de manipuler manuellement les noms de tables |
| 🧼 Maintenance simplifiée | Tu ajoutes un tenant, tu l’exécutes avec --vars et c’est bon |