La moitié des utilisateurs de Dagster Cloud exécutent dbt. Cette adoption reflète la qualité de l’intégration pour les workflows d’analytics engineering. L’intégration dagster-dbt traite chaque modèle dbt comme un data asset de premier ordre avec lignage automatique, suivi de fraîcheur et contrôles qualité. Pour les analytics engineers qui pensent déjà en dépendances ref() et en couches de modèles, cela correspond directement à votre façon de travailler.
Mon guide des fondamentaux Dagster couvre les concepts de base de la plateforme. Cet article approfondit l’intégration dbt elle-même : comment le mapping fonctionne, comment le personnaliser, et ce que vous gagnez par rapport à exécuter dbt seul.
Comment dagster-dbt mappe les modèles en assets
Le package dagster-dbt lit le fichier manifest.json de votre projet dbt et crée un asset Dagster par modèle, seed et snapshot. Les dépendances issues des appels ref() et source() dans votre SQL deviennent des arêtes dans le graphe d’assets Dagster. La fonction de calcul exécute dbt build en arrière-plan.
En code, la mise en place est simple :
from dagster_dbt import DbtCliResource, DbtProject, dbt_assetsfrom pathlib import Path
my_project = DbtProject(project_dir=Path("./transform"))my_project.prepare_if_dev()
@dbt_assets(manifest=my_project.manifest_path)def my_dbt_assets(context, dbt: DbtCliResource): yield from dbt.cli(["build"], context=context).stream()Trois choses se passent ici. DbtProject pointe Dagster vers le répertoire de votre projet dbt. prepare_if_dev() exécute dbt parse pour générer manifest.json pendant le développement local (en production, vous construisez le manifeste au moment du déploiement avec dagster-dbt project prepare-and-package). Le décorateur @dbt_assets lit ce manifeste et crée un asset par nœud.
Quand vous lancez dagster dev et ouvrez localhost:3000, chaque modèle dbt apparaît dans le catalogue d’assets avec ses dépendances amont et aval visualisées. Si mrt__marketing__campaign_performance dépend de int__google_ads__clicks et int__meta_ads__impressions, le graphe montre ces relations automatiquement, directement depuis vos appels SQL ref().
Personnaliser le mapping avec DagsterDbtTranslator
Le mapping par défaut fonctionne pour la plupart des projets, mais le DagsterDbtTranslator vous permet de contrôler comment les nœuds dbt deviennent des assets Dagster. Vous le sous-classez et surchargez des méthodes spécifiques.
Clés d’assets personnalisées
Par défaut, Dagster utilise le nom du modèle dbt comme clé d’asset. Si votre projet suit une convention de nommage par couches avec des préfixes comme base__, int__ et mrt__, les valeurs par défaut fonctionnent bien. Mais si vous devez mapper les modèles dans des groupes Dagster spécifiques ou ajuster les préfixes de clés :
from dagster_dbt import DagsterDbtTranslator, DbtCliResource, dbt_assetsfrom dagster import AssetKey
class CustomTranslator(DagsterDbtTranslator): def get_asset_key(self, dbt_resource_props): # Grouper les assets par chemin du modèle dbt : marts/marketing/model → ["marketing", "model"] node_path = dbt_resource_props["path"] components = Path(node_path).stem return AssetKey(components)
def get_group_name(self, dbt_resource_props): # Utiliser le dossier dbt comme groupe Dagster return Path(dbt_resource_props["path"]).parts[0]
@dbt_assets( manifest=my_project.manifest_path, dagster_dbt_translator=CustomTranslator(),)def my_dbt_assets(context, dbt: DbtCliResource): yield from dbt.cli(["build"], context=context).stream()Tags, propriétaires et métadonnées depuis dbt meta
Dagster lit la configuration meta de dbt. Les propriétés que vous définissez dans votre schema.yml sont transmises à l’interface Dagster :
models: - name: mrt__finance__monthly_revenue meta: dagster: owners: ["team:finance", "adrienne@example.com"] group: finance tags: - daily - critical columns: - name: revenue__total_usd description: "Total revenue in USD for the month"Les tags dbt correspondent aux tags Dagster. Les propriétaires spécifiés dans meta.dagster.owners apparaissent dans le catalogue d’assets et peuvent être utilisés pour filtrer le graphe de lignage par équipe.
Filtrer quels modèles deviennent des assets
Tous les nœuds dbt n’ont pas besoin d’être des assets Dagster. Les modèles éphémères ne produisent pas de tables, donc il n’y a pas de matérialisation à suivre. Vous pouvez les exclure en surchargeant get_asset_key pour retourner None, ou en utilisant la syntaxe de sélection dbt dans le paramètre select du décorateur @dbt_assets :
@dbt_assets( manifest=my_project.manifest_path, select="tag:dagster", # Seulement les modèles tagués 'dagster' dans dbt)def my_dbt_assets(context, dbt: DbtCliResource): yield from dbt.cli(["build"], context=context).stream()Cela vous donne un contrôle fin. Taguez les modèles critiques dans dbt, et seuls ceux-ci deviennent des assets suivis dans Dagster.
Les tests dbt comme asset checks
Depuis Dagster 1.7, les tests dbt sont automatiquement importés en tant qu’asset checks. Chaque test not_null, unique, accepted_values et test de données personnalisé apparaît dans l’interface Dagster comme un contrôle qualité attaché à l’asset concerné. Aucune configuration supplémentaire nécessaire.
À quoi cela ressemble-t-il en pratique ? Quand vous matérialisez un modèle dbt, ses tests s’exécutent dans le cadre du build. Dans l’interface Dagster, chaque asset affiche un badge de santé. Vert signifie matérialisé et tous les contrôles passés. Rouge signifie qu’un contrôle a échoué, et vous pouvez cliquer pour voir exactement quel test a échoué et pourquoi.
Les tests de schéma et les tests de données se comportent légèrement différemment. Les tests de schéma (comme not_null sur une colonne) s’attachent au modèle spécifique qu’ils testent. Les tests de données génériques qui référencent plusieurs modèles s’attachent au modèle principal.
Vous pouvez configurer la sévérité des contrôles via la configuration severity existante de dbt. Un test avec severity: warn ne bloquera pas les matérialisations en aval, tandis que severity: error le fera. Cela correspond à la distinction entre contrôles bloquants et non-bloquants de Dagster, donc votre configuration de tests dbt existante s’applique sans modifications.
Pour les équipes utilisant déjà des stratégies de test dbt, cela signifie une seule interface pour l’exécution et la qualité. Plus besoin de vérifier dbt Cloud pour les résultats de tests et un outil séparé pour la santé du pipeline.
Politiques de fraîcheur et planification
Dagster suit la fraîcheur des assets, pas seulement les horodatages d’exécution. Vous pouvez définir des attentes de fraîcheur dans la section meta de votre projet dbt :
models: - name: mrt__marketing__daily_spend meta: dagster: freshness_policy: maximum_lag_minutes: 360 # Doit avoir moins de 6 heuresCela indique à Dagster que mrt__marketing__daily_spend ne doit jamais avoir plus de 6 heures de retard. Si c’est le cas, l’interface affiche une alerte de fraîcheur, et vous pouvez configurer des notifications via les alertes Dagster+.
Pour l’orchestration basée sur un calendrier, build_schedule_from_dbt_selection crée un schedule Dagster directement à partir de la syntaxe de sélection dbt :
from dagster_dbt import build_schedule_from_dbt_selection
daily_dbt_schedule = build_schedule_from_dbt_selection( [my_dbt_assets], job_name="daily_dbt_job", cron_schedule="0 6 * * *", dbt_select="tag:daily",)Cela exécute tous les modèles dbt tagués daily à 6h du matin. Pour plus de flexibilité, les automation conditions et les sensors vous permettent d’aller au-delà des planifications fixes.
Un sensor peut surveiller un événement amont (une synchronisation Fivetran terminée, un fichier arrivant dans GCS, un pipeline dlt terminé) et déclencher dbt uniquement quand des données fraîches sont disponibles. Plus besoin de lancer dbt à 6h en espérant que le chargement amont soit terminé à temps.
from dagster import sensor, RunRequest
@sensor(job=my_dbt_job)def fivetran_complete_sensor(context): # Vérifier si la synchronisation Fivetran est terminée depuis la dernière vérification if fivetran_sync_completed(): yield RunRequest(run_key=f"fivetran-{context.cursor}")Configuration du projet : deux approches
L’approche Components (recommandée pour les nouveaux projets)
Depuis le cycle 1.12, Dagster recommande le DbtProjectComponent pour les nouvelles intégrations dbt. Le CLI dg génère tout automatiquement :
dg scaffold defs dagster_dbt.DbtProjectComponent transform \ --project-path ./transformCela crée un defs.yaml qui gère la compilation et la mise en cache du manifeste automatiquement. Le composant génère tous les assets depuis votre projet dbt avec un minimum de Python.
L’approche traditionnelle
Pour les projets existants ou les équipes souhaitant plus de contrôle, le scaffold traditionnel génère directement des fichiers Python :
dagster-dbt project scaffold \ --project-name my_project \ --dbt-project-dir ./transformCela produit un package Python avec le décorateur @dbt_assets, une définition DbtProject et la configuration des ressources. Vous éditez les fichiers Python directement pour personnaliser le comportement.
Gestion du manifeste
Le manifeste est le pont entre dbt et Dagster. Pendant le développement local, prepare_if_dev() ou le framework Components gère la génération du manifeste de façon transparente. Pour les déploiements en production, vous construisez le manifeste dans votre pipeline CI/CD. Une approche typique :
# Dans le pipeline CI/CDdbt deps --project-dir ./transformdagster-dbt project prepare-and-package \ --file ./my_project/project.pyCela compile le manifeste une seule fois au moment du déploiement, pour que Dagster n’ait pas besoin d’exécuter dbt parse en production.
Matérialisations sélectives et exécutions basées sur l’état
Vous n’avez pas besoin de matérialiser chaque modèle dbt à chaque exécution. Dans l’interface Dagster, vous pouvez sélectionner des assets spécifiques et ne matérialiser que ceux-ci, plus leurs dépendances en aval. C’est utile pour les corrections ad-hoc ou les backfills ciblés.
Pour les workflows CI/CD, Dagster supporte la sélection basée sur l’état. Raul Salamanca a documenté sur Medium comment il a répliqué le comportement state:modified de dbt Cloud dans Dagster pour un environnement BigQuery, en exécutant uniquement les modèles modifiés et leurs dépendances aval. Cela garde les builds CI rapides même dans les grands projets.
Pour le partitionnement temporel, le système de partitions de Dagster fonctionne avec les modèles incrémentaux dbt. Vous pouvez définir des partitions quotidiennes et matérialiser des plages de dates spécifiques, ce qui revient à passer --vars à dbt avec la date de partition.
Branch deployments pour le CI/CD dbt
Les branch deployments de Dagster+ sont particulièrement utiles pour les équipes dbt. Quand vous ouvrez une PR, Dagster crée automatiquement un environnement de preview éphémère avec vos modèles dbt modifiés et leur lignage. Vous pouvez voir exactement quels assets ont changé, inspecter le nouveau graphe de dépendances, et même lancer des matérialisations de test avant de merger.
C’est conceptuellement similaire aux jobs CI de dbt Cloud qui exécutent les modèles modifiés sur une PR, mais avec un périmètre plus large. Les branch deployments couvrent l’ensemble du graphe d’assets, pas seulement les modèles dbt. Si votre PR modifie un asset Python en amont d’un modèle dbt, vous voyez l’impact complet.
Pour les équipes pratiquant des tests dbt approfondis, les branch deployments ajoutent une couche de revue visuelle. Les reviewers peuvent inspecter le diff du graphe d’assets en parallèle du diff de code.
La vue d’ensemble
La transformation dbt est rarement le pipeline complet. Les données arrivent depuis des sources, sont transformées, puis alimentent des systèmes en aval. La valeur de Dagster se révèle quand tous ces éléments participent à un seul graphe d’assets.
Un pipeline de production sur BigQuery ressemble typiquement à :
- Ingestion : une synchronisation Fivetran ou un pipeline dlt charge les données brutes
- Transformation dbt : les modèles s’exécutent uniquement quand les données amont sont fraîches
- Assets Python : feature engineering ML, agrégations personnalisées, enrichissement via API
- Serving : des sensors déclenchent les rafraîchissements de dashboards Looker ou les exports reverse ETL
La gestion des dépendances cross-système est la partie qu’aucun cron job ni planificateur Cloud Run ne peut reproduire. Quand votre transformation dbt ne doit s’exécuter qu’après la fin d’une synchronisation Fivetran, et que votre rafraîchissement BI ne doit se déclencher qu’après que certains modèles mart sont frais, vous avez besoin d’un orchestrateur qui comprend les dépendances de données, pas seulement l’ordre d’exécution.
Quand choisir cette solution plutôt que dbt Cloud
dbt Cloud dispose d’un planificateur intégré qui gère les cron jobs, les vérifications de fraîcheur des sources et les builds CI sur les PRs. Pour les équipes qui ne font que des transformations SQL sans dépendances cross-système, cela fonctionne bien.
Mais dbt Cloud ne peut pas orchestrer les tâches non-dbt (ingestion, traitement Python, appels API), gérer les dépendances cross-système (déclencher dbt après une synchronisation), exécuter des exécutions partitionnées par date ou région, ni fournir un lignage unifié sur l’ensemble de votre stack de données.
Le calcul des coûts favorise souvent Dagster. Un projet dbt avec 100 modèles exécutés quotidiennement utilise environ 3 000 crédits par mois, ce qui tient confortablement dans Dagster+ Solo à 10 $/mois. dbt Cloud Starter coûte 100 $/utilisateur/mois. Pour une équipe de 3 personnes, cela fait 300 $/mois sur dbt Cloud contre 100 $/mois sur Dagster+ Starter, et avec Dagster vous obtenez l’orchestration sur l’ensemble de votre pipeline, pas seulement dbt.
La fusion Fivetran-dbt Labs d’octobre 2025 ajoute une dimension stratégique. Alors que dbt Cloud devient partie intégrante de la plateforme intégrée de Fivetran, les équipes qui souhaitent une indépendance vis-à-vis des fournisseurs dans leur couche d’orchestration ont une raison supplémentaire de garder l’orchestration séparée. Dagster ou Airflow comme couche d’orchestration vous donne la liberté de changer les outils d’ingestion, de transformation et de serving indépendamment.
Si votre équipe n’écrit que du SQL, n’a jamais besoin de coordination cross-système et ne se soucie pas du lignage au niveau des assets au-delà de ce que dbt fournit, dbt Cloud suffit. Dès que vous avez besoin de traitement Python, de déclencheurs événementiels ou d’une vue unifiée de la source au dashboard, l’intégration dagster-dbt gère cela bien. Comptez quelques semaines de montée en compétence sur les concepts Python et Dagster, mais Dagster University et la communauté grandissante rendent cela abordable.