Travailler avec dbt Mesh
Principe fondamental : Dans un projet mesh, les données en amont arrivent via ref(), pas source(). Chaque référence entre projets nécessite le nom du projet. En cas de doute, lisez d'abord dependencies.yml.
Quand utiliser
- Travailler dans un projet dbt qui référence des modèles d'autres projets dbt
- Résoudre l'ambiguïté quand plusieurs projets en amont ont des modèles au même nom (ex. plusieurs modèles
stg_) - Ajouter des contrats de modèles, des modificateurs d'accès, des groupes ou des versioning
- Configurer des références entre projets avec
dependencies.yml - Diviser un projet dbt monolithique en plusieurs projets mesh
À NE PAS utiliser pour :
- La construction générale de modèles ou le débogage (utilisez la skill
using-dbt-for-analytics-engineering) - Les tests unitaires de modèles (utilisez la skill
adding-dbt-unit-test) - Le travail de couche sémantique (utilisez la skill
building-dbt-semantic-layer)
D'abord : s'orienter dans une configuration multi-projets
Avant de rédiger ou modifier du SQL dans un projet utilisant dbt Mesh, suivez ces étapes :
1. Lire dependencies.yml
Ce fichier à la racine du projet vous indique quels projets en amont existent :
# dependencies.yml
projects:
- name: core_platform
- name: marketing_platform
Si ce fichier a une clé projects:, vous êtes dans une configuration mesh multi-projets. Chaque modèle que vous référencez depuis ces projets en amont doit utiliser ref() entre projets.
2. Comprendre comment les données en amont arrivent dans ce projet
Dans une configuration mesh, les modèles des projets en amont remplacent ce qui serait autrement des sources :
| Alternative | Mesh multi-projets |
|---|---|
{{ source('stripe', 'payments') }} |
{{ ref('core_platform', 'stg_payments') }} |
| Les données proviennent de tables brutes de la base de données | Les données proviennent des modèles publics d'un autre projet dbt |
Défini dans sources.yml |
Déclaré dans dependencies.yml |
Le projet en amont a déjà préparé et transformé les données brutes. Votre projet s'appuie sur ses modèles publics, pas ses sources brutes.
3. Désambiguïser les modèles au nom similaire
Quand plusieurs projets en amont ont des modèles avec le même nom (ex. stg_customers dans core_platform et marketing_platform), vous devez utiliser ref() à deux arguments :
-- Correct : nom de projet explicite, pas d'ambiguïté
select * from {{ ref('core_platform', 'stg_customers') }}
select * from {{ ref('marketing_platform', 'stg_customers') }}
-- FAUX : dbt ne peut pas déterminer lequel des stg_customers vous voulez
select * from {{ ref('stg_customers') }}
4. Vérifier les modèles existants dans la base de code
Avant de rédiger du nouveau SQL :
- Cherchez les appels
ref()existants à deux arguments pour voir quels projets et modèles en amont sont déjà utilisés - Regardez le YAML du projet en amont pour les modèles avec
access: public— seuls ceux-ci sont référençables entre projets - Le premier argument de
ref()doit correspondre exactement au champnamedansdbt_project.ymldu projet en amont (sensible à la casse)
5. Savoir ce que vous pouvez et ne pouvez pas référencer
| Accès du modèle en amont | Pouvez-vous le ref() entre projets ? |
|---|---|
access: public |
Oui |
access: protected (défaut) |
Non — uniquement au sein du même projet |
access: private |
Non — uniquement au sein du même groupe |
Si vous avez besoin d'un modèle qui n'est pas public, coordonnez-vous avec l'équipe en amont pour élargir son accès.
Les refs entre projets nécessitent dbt Cloud Enterprise
Les ref() entre projets et la clé projects: dans dependencies.yml ne sont disponibles que sur les plans dbt Cloud Enterprise ou Enterprise+. Avant de configurer une collaboration entre projets, vérifiez l'éligibilité du plan :
- Si
dependencies.ymla déjà une cléprojects:et le projet utilise activement des refs entre projets — Enterprise est déjà en place. Procédez. - Sinon — demandez à l'utilisateur de confirmer qu'il est sur dbt Cloud Enterprise ou Enterprise+ avant d'ajouter
projects:àdependencies.ymlou d'écrire de nouveaux appelsref()à deux arguments.
Si l'utilisateur ne peut pas confirmer le niveau du plan, ou confirme qu'il est sur un plan inférieur à Enterprise, ne configurez pas de refs entre projets. Expliquez que cette fonctionnalité nécessite une mise à jour vers Enterprise ou Enterprise+ et suggérez d'utiliser les fonctionnalités de gouvernance intra-projet à la place (groupes, modificateurs d'accès, contrats).
Syntaxe de ref() entre projets
-- Référencer un modèle en amont (dernière version)
select * from {{ ref('upstream_project', 'model_name') }}
-- Référencer une version spécifique
select * from {{ ref('upstream_project', 'model_name', v=2) }}
Pour les détails complets de la configuration entre projets (dependencies.yml, prérequis, orchestration), voir references/cross-project-collaboration.md.
Fonctionnalités de gouvernance
dbt Mesh inclut quatre fonctionnalités de gouvernance. Elles fonctionnent indépendamment et peuvent être adoptées progressivement :
| Fonctionnalité | Objectif | Config clé | Référence |
|---|---|---|---|
| Contrats de modèles | Garantir les noms de colonnes, types et contraintes au moment de la compilation | contract: {enforced: true} |
references/model-contracts.md |
| Groupes | Organiser les modèles par propriété équipe/domaine | group: finance |
references/groups-and-access.md |
| Modificateurs d'accès | Contrôler quels modèles peuvent vous référencer | access: public / protected / private |
references/groups-and-access.md |
| Versions de modèles | Gérer les changements de rupture avec des fenêtres de migration | versions: avec latest_version: |
references/model-versions.md |
Règle de placement YAML
Dans les fichiers YAML de propriétés de modèles, access, group et contract sont des configs et doivent toujours être imbriqués sous la clé config: — jamais placés comme propriétés de modèles au niveau supérieur. Les placer au niveau supérieur peut sembler fonctionner dans dbt Core mais provoque des erreurs d'analyse dans le moteur Fusion de dbt.
# ✅ CORRECT — toutes les configs de gouvernance sous `config:`
models:
- name: fct_orders
config:
group: finance
access: public
contract:
enforced: true
columns:
- name: order_id
data_type: int
# ❌ FAUX — configs de gouvernance comme propriétés au niveau supérieur (casse Fusion)
models:
- name: fct_orders
access: public # FAUX — pas sous config:
group: finance # FAUX — pas sous config:
contract: # FAUX — pas sous config:
enforced: true
columns:
- name: order_id
data_type: int
Ceci s'applique uniquement aux fichiers YAML de propriétés. Dans dbt_project.yml, utilisez le préfixe + pour l'attribution au niveau du répertoire (ex. +group: finance, +access: private). Dans les fichiers SQL, utilisez {{ config(access='public', group='finance') }}.
Ordre d'adoption
1. Groupes & Accès → 2. Contrats → 3. Versions → 4. Refs entre projets
(organiser les équipes) (verrouiller les formes) (gérer les changements) (diviser les projets)
- Groupes & Accès — aucun changement de schéma nécessaire, commencez par là
- Contrats — nécessitent de déclarer chaque colonne et type de données en YAML
- Versions — uniquement nécessaires quand un modèle contracté doit introduire un changement de rupture
- Refs entre projets — nécessitent dbt Cloud Enterprise ou Enterprise+ et un job de production en amont réussi. Ne configurez pas de refs entre projets si vous ne pouvez pas confirmer que le niveau du plan est Enterprise ou supérieur.
Contrats vs. Tests
| Contrats | Tests de données | |
|---|---|---|
| Quand | À la compilation (pré-vol) | Après compilation (post-vol) |
| Quoi | Noms de colonnes, types de données, contraintes | Qualité des données, règles métier |
| Échec | Le modèle ne se matérialise pas | Le modèle existe mais le test échoue |
| Utiliser pour | Garanties de forme pour les consommateurs en aval | Validation de contenu et détection d'anomalies |
Les contrats sont appliqués avant que les tests s'exécutent. Si un contrat échoue, le modèle n'est pas construit et aucun test ne s'exécute.
Cadre de décision
Ce modèle doit-il avoir un contrat ?
Utilisez un contrat quand :
- Le modèle est
access: public(surtout s'il est référencé entre projets) - D'autres équipes dépendent de la stabilité du schéma de ce modèle
- Le modèle alimente une exposition (tableau de bord, pipeline ML, reverse ETL)
- Les consommateurs externes (autres projets dbt, tableaux de bord BI, reverse ETL) interrogent la table directement et se casseraient suite à des renommages ou suppressions de colonnes
N'ajoutez PAS un contrat quand :
- Modèles de préparation (
stg_*) — ce sont des détails d'implémentation interne, pas des API orientées consommateurs - Le modèle est encore en évolution — si l'utilisateur dit qu'il itère sur la conception, conseillez d'attendre que le schéma se stabilise
- Aucun consommateur externe n'existe — dans une configuration monoprojet sans refs entre projets, sans outils BI dépendant du schéma et sans expositions, les contrats ajoutent une surcharge de maintenance sans bénéfice. Posez des questions sur les consommateurs avant de recommander des contrats.
- Colonnes dynamiques/pivot — les modèles qui utilisent
pivot(),unpivot()ou génèrent dynamiquement des colonnes sont de mauvais candidats car la liste des colonnes n'est pas fixe et le contrat se cassera chaque fois que les valeurs dynamiques changent - Modèles éphémères — les contrats ne sont pas supportés sur les matérialisations éphémères
Si l'utilisateur demande un contrat sur un modèle qui correspond aux critères "À NE PAS ajouter" ci-dessus, déconseille-le et explique pourquoi. Ne vous contentez pas de vous conformer — l'utilisateur peut ne pas réaliser que le contrat est inapproprié. Suggérez des alternatives (ex. tests de données pour les modèles de préparation, attendre la stabilité du schéma, ou changer la matérialisation pour les modèles éphémères).
Ce modèle doit-il être versionné ?
Versionnez un modèle quand :
- Il a un contrat appliqué ET vous devez introduire un changement de rupture (suppression de colonne, renommage, changement de type)
- Les consommateurs en aval ont besoin d'une fenêtre de migration avant que l'ancienne forme disparaisse
Ne versionnez PAS un modèle :
- Pour les changements additifs (nouvelles colonnes) — ce sont des changements non-rupture
- Pour les corrections de bugs — corrigez sur place
- De manière préventive « au cas où » — versionnez uniquement quand un changement de rupture est réellement nécessaire
Quel niveau d'accès ce modèle doit-il avoir ?
Est-il référencé entre projets ?
└─ Oui → public (contrat recommandé)
└─ Non
Est-il référencé en dehors de son groupe ?
└─ Oui → protected (défaut)
└─ Non
Est-il interne à une petite équipe ?
└─ Oui → private
└─ Non → protected (défaut)
Bonne pratique : Définissez par défaut les nouveaux modèles à private et élargissez l'accès uniquement si nécessaire. Le défaut protected est permissif — soyez intentionnel.
Erreurs courantes
| Erreur | Pourquoi c'est faux | Correction |
|---|---|---|
Utiliser ref() à argument unique dans les configurations multi-projets |
Ambigu — dbt peut ne pas résoudre vers le projet prévu | Utilisez toujours ref('project_name', 'model_name') pour les refs entre projets |
Utiliser source() pour les données de projets en amont |
Dans mesh, les données en amont arrivent via les modèles publics, pas les sources brutes | Utilisez ref('upstream_project', 'model_name') à la place |
Ne pas lire dependencies.yml en premier |
Vous ne saurez pas quels projets en amont existent ou comment ils s'appellent | Lisez toujours dependencies.yml avant de rédiger du SQL entre projets |
Rendre tous les modèles public |
Expose les détails d'implémentation interne entre projets | Marquez public uniquement les modèles qui sont des APIs intentionnelles pour d'autres équipes |
| Sauter les contrats sur les modèles publics | Les consommateurs en aval peuvent se casser silencieusement quand le schéma change | Appliquez toujours les contrats sur les modèles access: public |
| Versionner pour les changements non-rupture | Crée une surcharge de maintenance inutile et un coût d'entrepôt | Versionnez uniquement pour les changements de rupture (suppression de colonne, changement de type, renommage) |
Oublier dependencies.yml |
Les refs entre projets échouent sans déclarer le projet en amont | Ajoutez le projet en amont à dependencies.yml avant d'utiliser ref() à deux arguments |
| Référencer des modèles non-publics entre projets | Seuls les modèles public sont disponibles pour les autres projets |
Définissez access: public sur les modèles destinés à la consommation entre projets |
Placer access, group ou contract comme propriétés de modèles au niveau supérieur en YAML |
Casse l'analyse du moteur Fusion ; le placement au niveau supérieur n'est pas une config valide | Imbriquez toujours sous config: — ex. config: { access: public } |
| Ajouter des contrats aux modèles de préparation | Les modèles de préparation sont internes — les contrats ajoutent de la friction sans protéger les consommateurs externes | Déconseille-le ; suggérez les tests de données à la place |
| Ajouter des contrats aux modèles avec colonnes dynamiques/pivot | La liste des colonnes change avec les données, cassant le contrat | Déconseille-le ; expliquez pourquoi la liste des colonnes n'est pas fixe |
| Ajouter des contrats sans établir de consommateurs externes | Les contrats protègent une limite de schéma — pas de consommateurs signifie pas de limite à protéger | Demandez qui dépend de ce modèle avant d'ajouter un contrat |
Rendre un modèle private alors qu'il est déjà référencé en dehors de son groupe |
Les refs existantes se cassent avec une DbtReferenceError |
Élargissez l'accès à protected ou refactorisez les appelants dans le même groupe d'abord |
| Configurer des refs entre projets sans confirmer dbt Cloud Enterprise | Le ref() entre projets n'est pas disponible sur les niveaux de plan inférieurs |
Confirmez le niveau du plan avant d'ajouter projects: à dependencies.yml ou d'écrire des appels ref() à deux arguments |
Ajouter dependencies.yml sans un job de production en amont réussi |
dbt Cloud résout les refs entre projets via le manifest.json en amont — pas d'exécution de job signifie pas de manifeste |
Exécutez d'abord au moins un déploiement de production réussi dans le projet en amont |