Catalyst vs dbt tests : surveiller au-delà de vos modèles

Les tests dbt sont des assertions exécutées au moment du build, sur les modèles que dbt gère. Catalyst surveille n'importe quelle table selon sa propre planification, y compris les sources que dbt ne touche jamais.

· 11 min read

Les tests dbt et Catalyst ne sont pas vraiment concurrents, et prétendre le contraire vous ferait perdre votre temps. Les tests dbt sont des assertions qui s'exécutent à l'intérieur d'un build de transformation, sur les modèles que dbt gère, au moment où dbt tourne — c'est exactement le bon endroit pour attraper une jointure qui a explosé ou une clé primaire qui a cessé d'être unique. Catalyst est une surveillance continue qui s'exécute selon une planification sur n'importe quelle table de votre entrepôt, y compris les sources brutes et les tables chargées par des fournisseurs que dbt ne touche jamais, avec une interface et un historique d'exécutions utilisables par un profil non technique. Si vous utilisez déjà dbt, gardez vos tests dbt ; la question est de savoir ce qui couvre tout ce qui se trouve en amont et en aval.

Ce que sont réellement les tests dbt

Un test dbt est une requête SQL censée ne renvoyer aucune ligne. C'est tout le modèle, et sa simplicité explique pourquoi il fonctionne si bien.

Quatre tests génériques sont livrés avec dbt lui-même, déclarés dans un schema.yml à côté du modèle :

version: 2

models:
  - name: orders
    columns:
      - name: order_id
        tests:
          - unique
          - not_null
      - name: status
        tests:
          - accepted_values:
              values: ['pending', 'paid', 'shipped', 'refunded']
      - name: customer_id
        tests:
          - relationships:
              to: ref('customers')
              field: id

dbt test compile chacun d'eux en un select qui renvoie les lignes fautives, l'exécute sur l'entrepôt, et échoue si quelque chose remonte. Des packages étendent considérablement le vocabulaire — dbt_utils ajoute des tests d'expression et de combinaison de colonnes, dbt-expectations porte une grande partie du catalogue Great Expectations dans le YAML de dbt — et les tests singuliers vous permettent de déposer un fichier .sql brut dans tests/ pour affirmer tout ce que vous pouvez exprimer dans une requête.

C'est un système réellement bien conçu. Les tests vivent à côté du modèle qu'ils décrivent, ils sont relus dans la même pull request que la transformation, ils s'exécutent en CI, et ils ne coûtent rien au-delà du calcul de l'entrepôt. Si votre problème de qualité des données est « nos transformations cassent parfois », les tests dbt le résolvent.

Là où les tests dbt s'arrêtent

Ces limites ne sont pas des défauts. Elles découlent directement de ce qu'est dbt : un framework de transformation, pas un produit de surveillance.

Ils s'exécutent quand dbt s'exécute. Un test dbt est un événement dans un build. Si votre build est nocturne, votre latence de détection est d'une journée — et si une table est chargée par Fivetran à 06:00 alors que dbt tourne à 02:00, le contrôle vous parle de la veille. Pire : si le build échoue tôt ou si l'orchestrateur le saute, aucun test ne s'exécute, et le silence ressemble en tout point à un succès.

Ils couvrent les modèles que dbt gère. Les sources peuvent également être testées, et dbt source freshness est un contrôle utile, mais la frontière de couverture reste le projet dbt. L'export CRM qui atterrit dans un schéma de staging, le tableur financier que quelqu'un dépose chaque mois, la base de production répliquée que trois équipes interrogent directement — rien de tout cela n'est un modèle dbt, et c'est souvent là que naissent les incidents.

Il n'y a ni historique ni interface. Les résultats des tests dbt existent dans les logs de l'exécution et dans run_results.json. Répondre à « ce contrôle échoue-t-il par intermittence depuis trois semaines ? » suppose d'analyser des artefacts ou de mettre en place Elementary ou dbt Cloud. Répondre à « lesquels de nos jeux de données critiques sont couverts en fraîcheur ? » suppose de faire des grep dans du YAML. Les lignes en échec peuvent être matérialisées avec store_failures, mais encore faut-il que quelqu'un sache que la table existe et aille l'interroger.

Les alertes sont le travail de quelqu'un d'autre. dbt sort avec un code non nul ; Airflow, Dagster, GitHub Actions ou dbt Cloud transforment cela en notification. Cette notification dit généralement « le job dbt a échoué », et non « la colonne status de orders a vu apparaître une valeur que personne n'attendait ». Router une défaillance précise vers la personne responsable de ce jeu de données, c'est un travail que vous construisez vous-même.

Ils s'adressent à ceux qui écrivent du YAML dans un dépôt. C'est la contrainte qui décide de la plupart des discussions d'outillage. La personne qui sait qu'un remboursement ne peut jamais dépasser le montant de la commande d'origine travaille généralement à la finance, pas dans votre projet dbt. Elle a le choix entre ouvrir un ticket ou ne pas consigner la règle, et c'est le plus souvent la seconde option qui l'emporte.

Ce que Catalyst ajoute

Catalyst est une application web qui se connecte en lecture seule à votre entrepôt et surveille les tables selon la planification que vous choisissez. Concrètement, face à la liste ci-dessus :

Vue comparative

dbt testsCatalyst
NatureAssertions à l'intérieur d'un framework de transformationSurveillance continue de la qualité des données
Moment d'exécutionPendant un build dbtSelon une planification que vous définissez, indépendante de tout build
PérimètreModèles et sources du projet dbtN'importe quelle table d'une base connectée, plus les fichiers importés
Format des règlesTests schema.yml, plus packages et tests SQL singuliersContrats ODCS en YAML, édités en YAML ou visuellement
Qui écrit les règlesLes analytics engineers, dans un dépôtToute personne ayant un accès, dans un navigateur
HistoriqueLogs et run_results.jsonHistorique d'exécutions stocké par règle, avec tendances
Lignes en échecstore_failures vers une tableJusqu'à cinq exemples par contrôle, dans l'interface
AlertesVia votre orchestrateur ou dbt CloudPas à l'heure où nous écrivons
Contrôle d'accèsPermissions GitRôles, SSO, journal d'audit
CoûtGratuit, plus le calcul de l'entrepôtOffre gratuite Starter, puis par utilisateur — voir les tarifs

Restez aux seuls tests dbt lorsque

Il existe un ensemble bien réel d'équipes pour lesquelles ajouter un deuxième outil est un surcoût sans retour. Vous en faites probablement partie si la plupart de ces points sont vrais :

Si cela vous décrit, n'achetez rien. Ajoutez dbt source freshness si ce n'est pas déjà fait, activez store_failures sur les tests qui comptent, et retournez à votre travail.

Cette liste cesse de décrire la plupart des équipes à peu près au moment où une deuxième équipe commence à dépendre de vos données, ou lorsque le premier incident prend naissance dans une table dont dbt n'a jamais entendu parler.

Utiliser les deux : une division du travail raisonnable

Les équipes qui utilisent les deux aboutissent généralement au même partage, et il vaut la peine de l'énoncer clairement, car cela évite de dupliquer des règles.

Les tests dbt possèdent la justesse au moment du build. Tout ce dont l'échec doit empêcher la publication d'un modèle : unicité de la granularité, non-nullité sur les clés, intégrité référentielle entre modèles, valeurs autorisées sur les énumérations que vous contrôlez, vraisemblance du nombre de lignes après une jointure. Gardez-les dans le dépôt, relus en même temps que le SQL qu'ils protègent.

Catalyst possède la promesse. Tout ce qui décrit ce qu'un jeu de données garantit à ses consommateurs, quel que soit le pipeline qui l'a écrit aujourd'hui : fraîcheur, complétude sur les colonnes critiques pour le métier, plages qui encodent des règles métier, valeurs autorisées sur les champs détenus par un autre système. Ce sont les énoncés durables : ils ont leur place dans un contrat versionné, et ils doivent être vérifiés qu'un build ait tourné ou non.

Les sources se surveillent, elles ne se testent pas. Les tables d'atterrissage brutes sont là où la plupart des incidents entrent, et ce sont par définition celles sur lesquelles votre framework de transformation a le moins de prise. Les surveiller au rythme propre du chargement, c'est là que la vérification continue se rentabilise le plus vite.

Le point de départ concret n'est pas « migrez vos tests dbt ». C'est : listez les cinq tables dont dépend votre tableau de bord le plus consulté, notez lesquelles dbt gère réellement, et mettez de la surveillance sur les autres. Cela représente deux heures de travail, et cela finit généralement par trouver quelque chose dès la première semaine. Pour la méthode générale, voyez le guide sur la validation de vos données.

Questions fréquentes

Catalyst remplace-t-il les tests dbt ?

Non, et il n'est pas conçu pour cela. Les tests dbt sont des assertions au moment du build qui doivent empêcher la publication d'un modèle cassé, et c'est le bon outil pour cela. Catalyst s'exécute selon une planification sur n'importe quelle table, y compris les sources et les jeux de données que dbt ne gère pas, et il ajoute l'historique d'exécutions, les exemples de lignes en échec et l'accès pour les profils non techniques. La plupart des équipes qui adoptent Catalyst conservent tous les tests dbt qu'elles avaient déjà.

Les tests dbt peuvent-ils surveiller des tables que dbt n'a pas construites ?

En partie. Vous pouvez déclarer une table externe comme source et lui attacher des tests, et dbt source freshness vérifie la date de sa dernière mise à jour. La limite tient au moment d'exécution plutôt qu'au périmètre : ces contrôles ne s'exécutent toujours que lorsque dbt s'exécute, si bien qu'une source qui casse à 06:00 reste non signalée jusqu'au build suivant. Pour les tables entièrement hors du projet, ou chargées par des outils suivant leur propre planification, une surveillance planifiée détecte le problème au moment où il survient.

Quelle est la différence entre un test dbt et un contrat de données ?

Un test dbt est une assertion exécutée par un outil précis à un point précis d'un pipeline. Un contrat de données est une description versionnée de ce qu'un jeu de données promet — schéma, responsabilité, niveaux de service et règles de qualité — écrite dans un format indépendant de ce qui exécute les contrôles. Catalyst utilise l'Open Data Contract Standard, de sorte que les règles restent portables et relisibles sous forme de fichiers plutôt que d'être enfermées dans le produit d'un éditeur.

Comment être alerté quand un test dbt échoue ?

dbt se termine avec un statut non nul, et votre orchestrateur ou dbt Cloud convertit cela en notification. Vous construisez le routage vous-même, et le message porte généralement sur le job plutôt que sur le contrôle précis. Catalyst n'envoie pas de notifications à l'heure où nous écrivons : il exécute chaque règle selon sa propre planification et enregistre le résultat, de sorte que le tableau de bord montre quelle règle a échoué, sur quel jeu de données, depuis combien d'exécutions elle échoue, et jusqu'à cinq exemples de lignes qui l'ont enfreinte.

Dois-je réécrire mes tests dbt pour utiliser Catalyst ?

Non. Laissez-les où ils sont. Catalyst importe le schéma des tables que vous connectez et propose un ensemble de règles de base à partir des colonnes, des clés et des horodatages qu'il y trouve : vous commencez donc par relire des suggestions plutôt que par porter quoi que ce soit. En pratique, les règles que vous ajoutez sont celles que les tests dbt n'étaient de toute façon pas en position de couvrir.