Mon meilleur ami… C’est dbt test

www.getdbt.com

Yabir : Combien de fois avons-nous fait une modification sur notre pipeline qui a eu pour conséquence de briser la logique à un autre niveau ?

John doe : Ok, mais pour cela, nous enregistrons tout ce que nous faisons dans notre Jira ou un document de spécifications fonctionnelles, nous avons donc un historique des modifications.

Yabir : C'est très bien, mais combien de fois examines-tu ces documents avant d'y apporter des modifications ? Allons plus loin ! Combien de fois as-tu modifié ce document pour chaque modification que tu fais ?

Admettons-le ! Nous ne sommes pas très doués pour nous souvenir des anciens tickets ou pour nous fier à l’historique du travail effectué. Je ne blâme personne, c’est la vitesse à laquelle les choses se passent qui nous oblige à avoir une mémoire de poisson rouge (on pourra discuter plus tard de s’il est vrai que ce poisson a la mémoire courte).

Compte tenu de ce principe universel, nous devons chercher du soutien et nos amis de dbt Labs l’ont compris depuis longtemps : testons avant de déployer !


Pour cela dbt propose la fonctionnalité “dbt test” qui nous permet de faire des déclarations sur nos données et de les valider.

TL;DR

Voilà mon petit résumé à la chatGPT 😉

  • dbt test nous permet de vérifier une assertion de nos données.
  • Il existe deux types de tests et tu peux les personnaliser :
    • Singular : spécifique pour un modèle.
    • Generic: un test pouvant être réutilisé dans plusieurs modèles.
  • Des alertes peuvent être configurées par mail ou slack.
  • Si tu veux faire de tests complexes, tu peux toujours aller au hub pour récupérer un package.
  • --store-failures te permet d’enregistrer tes données invalides dans une table.
  • Une documentation peut être ajoutée aux tests.

Tout d’abord : C’est quoi un test ?

Les tests ne sont rien d’autre que de simples requêtes SQL qui peuvent être spécifiques à un modèle. Ces tests peuvent être spécifiques (singular) ou génériques (generic).

Tests Singular

Un test singulier est une requête SQL pour obtenir les données invalides. Par exemple, voici la requête pour obtenir les numéros téléphone qui ont moins de 10 chiffres :

-- Numéros de téléphone de moins de 10 chiffres. Règle de gestion ticket SDB-207.
select 
	id_utilisateur,
	tel,
from {{ source(erp_utilisateurs) }}
where length(tel) < 10

Ces tests sont généralement utilisés pour vérifier une affirmation spécifique d’un modèle.

Tests Generic

Il existe également des tests génériques, ceux-ci sont natifs de dbt et peuvent être appliqués à littéralement n’importe quel modèle en tapant simplement le nom du test. Par exemple, si je veux obtenir les données nulles d’une colonne, je peux ajouter le nom du test à la liste dans la configuration yaml :

version: 2

models:
  - name: stg_utilisateurs
    columns:
      - name: tel
        tests:
          - not_null

Cela compilera comme suit :

select *
from <<environnement>>.stg_utilisateurs
where tel is null

Il existe 4 types de tests dbt natifs :

  • unique : vérifie l’unicité de la colonne.
  • not_null : vérifie si la colonne est remplie.
  • accepted_values : vérifie que les données d’une colonne font partie d’une liste de valeurs valides.
  • relationships : vérifie que les données de la colonne existent dans une autre table.

Promotion d’un test singulier en générique

Si vous souhaitez transformer votre test singulier en un test générique, utilise simplement le macro “test“.

Par exemple, si je vais appliquer mon test des téléphones à la table des collaborateurs, ou des partenaires, je peux créer un test “check_telephone_invalide“. Ce test peut prendre le nom du modèle et le nom de la colonne comme arguments :

{% test check_telephone_invalide(model, column_name) %}

    select *
    from {{ model }}
    where length( {{ column_name }} ) < 10

{% endtest %}

Exécution

Exécutez simplement la commande dbt test pour exécuter tous les tests.

Vous pouvez également utiliser --select pour tester des modèles spécifiques. Par exemple :

dbt test --select stg_utilisateurs

Comment stocker les données invalides ?

L’option --store-failures vous permet d’enregistrer les données invalides dans une table de votre cloud datawarehouse :

dbt test -s stg_utilisateurs --store-failures

Cette option peut également être activée dans la configuration YAML :

version: 2

models:
  - name: my_model
    columns:
      - name: my_column
        tests:
          - unique:
              config:
                store_failures: true  # always store failures

dbt créera un schéma (ou dataset) dédié pour ce test dans le cloud datawarehouse.

Ne réinventons pas la roue ! Profitons des packages

dbt dispose d’un catalogue complet de tests prêts à l’emploi et validés par dbt Labs ou par la communauté. Alors n’hésite pas à les utiliser !

Les packages que j’apprécie le plus sont :

  • dbt_utils : c’est la base de la base ! Tu as déjà eu le cas où il faut sélectionner toutes les colonnes SAUF une ou deux? Alors avec dbt_utils tu peux le faire avec une seule ligne. Mais il n’y a pas que ça, tu as de tests, des macros, des générateurs de SQL, …
  • audit_helper : Est-ce que ça t’est déjà arrivé de devoir comparer deux tables “à la main” pour récupérer ses différences en faisant des jointures? Alors ce package te permet de comparer des tables par colonnes, par relations, par requêtes, etc…
  • dbt_project_evaluator : Ma dernière recommandation est ce package peu connu qui te permet d’évaluer si ton projet suit les bonnes pratiques dbt (si tous tes modèles sont testés, si tu utilises les sources…)

Et l’intégration continue ?!

“Qu’est-ce qu’un peintre sans son pinceau ? C’est la même chose que les tests dbt sans intégration continue (CI)”. – Yabir

C’est beau, non ?

Nous pouvons intégrer les tests à un flux de déploiement où à chaque pull request (PR), les tests s’exécutent automatiquement pour vérifier que les modifications apportées s’intègrent bien au pipeline. Tout cela s’exécute sur un environnement dédié pour la CI bien sûr.

Comment ? Avec dbt Cloud par exemple :

  1. Créer un job sur dbt Cloud et remplir les paramètres initiaux
  2. Dans la partie Triggers, sur l’onglet Webhook, cocher “Run on Pull Request ?”

Et voilà ! Dès le moment qu’un développeur fait son Pull Request, le client Git lance les tests automatiquement. Cela permet au responsable des PR de s’assurer que les modifications s’intègrent bien à tout le projet avant de faire le check du code.

dbt Courses

D’autres options à connaître

  • Indiquer un responsable pour les tests en utilisant la config : “config.meta.owner.name”
  • Alertes par mail ou par Slack en cas d’erreur
  • Documenter les tests en ajoutant une description en markdown

Points clés à retenir

“Tester mène à l’échec et l’échec mène à la compréhension” -Burt Rutan

Dbt test est une des fonctionnalités les plus intéressantes de dbt. Elle permet de mettre en place un déploiement CI, d’alerter, et surtout d’assurer la qualité de nos données.

Mes recommandations personnelles :

  • Commence par les tests Generic et mets au moins un test “unique” pour les clés primaires.
  • Priorise les tests des packages si tu cherches à personnaliser un test.
  • Documente tes tests ! Tu peux ajouter des définitions et un responsable pour vérifier les alertes.
  • Teste tes sources dbt. Le plus tôt on identifie une erreur, le mieux c’est.

Je t’encourage à jouer avec les différents types de tests et à ne pas les laisser de côté dans ton projet. Pense également à les mettre à jour en fonction des règles de gestion appliquées.

Si tu as de questions ou si tu veux une démo de comment développer une des fonctionnalités présentées, n’hésite pas à nous contacter. On pourra organiser un webinar ou une présentation “singular” :3

Liens utiles

Yabir Canario de la Mota

Data Engineer avec 6+ d'expérience, certifié Azure Data Engineer et dbt Developer

1 comment on “Mon meilleur ami… C’est dbt test

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *