ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Organisation des métriques dans les projets dbt

Comment organiser les modèles sémantiques et les métriques dans dbt — structures co-localisée vs sous-dossiers parallèles, la règle d'une entité primaire et les patterns de mise à l'échelle pour les grands projets

Planté
dbtdata modelinganalytics

Les décisions clés pour organiser les fichiers YAML de modèles sémantiques et de métriques sont leur emplacement par rapport aux modèles SQL et la façon dont les modèles sémantiques se mappent aux couches dbt existantes. Une approche co-localisée convient aux petits projets ; les projets plus grands bénéficient d’une structure de sous-dossiers parallèles.

Structure co-localisée

Pour les projets avec moins de 20 métriques, conservez les modèles sémantiques et les métriques avec le modèle SQL qu’ils décrivent :

models/
marts/
mrt__finance__orders.sql
mrt__finance__orders.yml # semantic model + metrics
mrt__sales__customers.sql
mrt__sales__customers.yml # semantic model + metrics

Le fichier YAML contient à la fois la définition du modèle sémantique et les métriques construites à partir de lui. Cela reflète la convention dbt standard de co-localiser les configs de modèles avec les fichiers SQL.

L’avantage est la simplicité. Quand on ouvre un modèle, on voit ses métriques directement. Quand on modifie le SQL, on voit immédiatement quelles métriques pourraient être affectées.

La limitation est que les métriques couvrent souvent plusieurs modèles sémantiques. Une métrique customer_lifetime_value pourrait référencer des mesures des modèles orders et customers. Dans une structure co-localisée, où cette métrique doit-elle résider ? On finit par prendre des décisions de placement arbitraires qui enfreignent la règle du « trouver en 10 secondes ».

Structure avec sous-dossiers parallèles

Pour les projets plus grands, séparez les modèles sémantiques des métriques et organisez par domaine :

models/
marts/
mrt__finance__orders.sql
mrt__sales__customers.sql
semantic_models/
orders.yml
customers.yml
metrics/
revenue_metrics.yml
customer_metrics.yml
conversion_metrics.yml

Cette structure passe à l’échelle parce que les métriques inter-modèles ont un emplacement naturel. customer_lifetime_value va dans customer_metrics.yml quelle que soit les modèles sémantiques qu’elle référence. Les métriques de revenu qui combinent des données de commandes et de remboursements vont dans revenue_metrics.yml.

Le regroupement de fichiers de métriques par domaine reflète la façon dont les utilisateurs pensent aux métriques. « Où sont les métriques de revenu ? » a une réponse évidente : metrics/revenue_metrics.yml. Cela s’aligne avec la convention de nommage basée sur les préfixes où toutes les métriques de revenu commencent par revenue_.

Le compromis est l’indirection. Modifier mrt__finance__orders.sql nécessite de vérifier un répertoire séparé pour les modèles sémantiques et métriques affectés. Dans une structure co-localisée, l’impact est visible immédiatement.

La règle d’une seule entité primaire

Chaque modèle sémantique doit avoir exactement une entité primaire, généralement alignée sur l’un des modèles de la couche mart :

semantic_models:
- name: orders
defaults:
agg_time_dimension: ordered_at
model: ref('mrt__finance__orders')
entities:
- name: order
type: primary
- name: customer
type: foreign
- name: product
type: foreign

L’entité primaire (order) identifie ce que représente chaque ligne. Les entités étrangères (customer, product) permettent les jointures avec d’autres modèles sémantiques. MetricFlow utilise ces relations d’entités pour construire le graphe sémantique — la carte de la façon dont les données sont connectées.

Cette contrainte maintient la navigabilité du graphe. Si un modèle sémantique a deux entités primaires, MetricFlow ne peut pas déterminer le grain du modèle, et les jointures deviennent ambiguës. Une ligne, une entité primaire, sans exception.

Le mapping est généralement simple : votre mart mrt__finance__orders se mappe au modèle sémantique orders avec l’entité primaire order. Votre mart mrt__sales__customers se mappe au modèle sémantique customers avec l’entité primaire customer. Le modèle sémantique est une couche fine sur le mart, ajoutant des annotations d’entités, de dimensions et de mesures aux colonnes qui existent déjà.

Les modèles sémantiques se mappent aux marts

Les modèles sémantiques doivent référencer les modèles de la couche mart, pas les modèles de base ou intermédiaires. C’est cohérent avec l’architecture trois couches : les marts sont la couche de consommation. Les modèles sémantiques s’assoient au-dessus de cette couche de consommation, ajoutant des métadonnées pour la couche sémantique.

Pointer un modèle sémantique vers un modèle intermédiaire crée un couplage fragile. Les modèles intermédiaires sont internes au projet dbt — ils peuvent être refactorisés, divisés ou fusionnés sans préavis pour les consommateurs en aval. Les marts, en revanche, sont des interfaces stables avec des consommateurs définis.

# Bien : modèle sémantique sur un mart
semantic_models:
- name: orders
model: ref('mrt__finance__orders')
# Mal : modèle sémantique sur un intermédiaire
semantic_models:
- name: orders
model: ref('int__order__order_lj_customer')

Le modèle intermédiaire pourrait changer de grain ou être renommé lors d’un refactoring. Le mart est un contrat avec ses consommateurs.

Validation en CI

Quelle que soit l’organisation des fichiers, validez la couche sémantique en CI :

.github/workflows/dbt.yml
- name: Validate semantic layer
run: dbt sl validate
Terminal window
# Ou pour dbt Core :
mf validate-configs

MetricFlow valide à trois niveaux :

  1. Validation du parsing — Le YAML suit-il le schéma ?
  2. Validation sémantique — Les noms sont-ils uniques ? Les références existent-elles ? Y a-t-il exactement une entité primaire ?
  3. Validation de la plateforme de données — Les colonnes référencées existent-elles dans les tables physiques ?

Ajoutez --verbose-issues --show-all lors du débogage des échecs. La validation détecte les références cassées, les noms dupliqués et les entités manquantes avant qu’ils n’atteignent la production.

C’est particulièrement important avec la structure de sous-dossiers parallèles, où une modification d’un modèle sémantique dans un répertoire peut casser des métriques définies dans un autre. La validation CI est le filet de sécurité qui rend la séparation des fichiers sûre.

Quand restructurer

Le signal pour passer d’une structure co-localisée à une structure parallèle n’est pas un nombre spécifique de métriques. C’est le moment où vous vous retrouvez à placer une métrique dans un fichier où elle n’a pas logiquement sa place parce qu’« elle doit aller quelque part ». C’est le signe que la structure co-localisée montre ses limites.

Un projet avec 30 métriques qui se mappent toutes 1-pour-1 à des modèles sémantiques uniques fonctionne bien avec la co-localisation. Un projet avec 15 métriques dont la moitié sont des métriques dérivées ou ratio couvrant plusieurs modèles sémantiques nécessite la structure parallèle dès le premier jour.

Commencez co-localisé. Migrez quand les décisions de placement deviennent arbitraires. La restructuration est un déplacement de fichiers, pas un changement de logique — les définitions de métriques et de modèles sémantiques restent identiques quel que soit le répertoire dans lequel elles se trouvent.