dbt: Validation de date avec macros avec error()


L’utilisation de la fonction error() dans les macros dbt pour valider des paramètres de date est une technique puissante pour bloquer les erreurs avant que du SQL ne soit exécuté.


🎯 Objectif

Tu veux t’assurer que les dates passées à tes modèles :

  • ✅ sont bien au bon format (YYYY-MM-DD),
  • 🧠 ont une logique correcte (ex : date de début < date de fin),
  • ❌ et planter tôt avec un message clair si une erreur est détectée.

🧩 Solution : utiliser dbt.exceptions.error() dans une macro

Cette fonction lève une erreur de compilation Jinja, donc avant même que le SQL n’arrive à la base de données.


✅ Exemple 1 : valider un format de date avec une regex

📄 macro validate_date.sql

{% macro validate_date(date_string) %}
    {% if not date_string is string %}
        {{ exceptions.error("🚨 La valeur '" ~ date_string ~ "' n'est pas une chaîne de caractères.") }}
    {% endif %}

    {% if not date_string.match(r'^\d{4}-\d{2}-\d{2}$') %}
        {{ exceptions.error("🚨 La date '" ~ date_string ~ "' n'est pas au format YYYY-MM-DD.") }}
    {% endif %}
{% endmacro %}

🔎 match() est une fonction de Jinja, utilisable via le filtre regex_match si besoin.


✅ Exemple 2 : valider un intervalle logique entre deux dates

{% macro validate_date_range(start_date, end_date) %}
    {{ validate_date(start_date) }}
    {{ validate_date(end_date) }}

    {% set sd = modules.datetime.strptime(start_date, "%Y-%m-%d") %}
    {% set ed = modules.datetime.strptime(end_date, "%Y-%m-%d") %}

    {% if sd >= ed %}
        {{ exceptions.error("🚨 La date de début (" ~ start_date ~ ") doit être antérieure à la date de fin (" ~ end_date ~ ").") }}
    {% endif %}
{% endmacro %}

✅ Utilise le module datetime embarqué de Jinja pour comparer les dates.


📄 Exemple d’utilisation dans un modèle dbt

-- models/fact_ventes.sql

{% set start_date = var('start_date', '2024-01-01') %}
{% set end_date   = var('end_date', '2024-12-31') %}

{{ validate_date_range(start_date, end_date) }}

select *
from {{ ref('stg_ventes') }}
where date_vente between '{{ start_date }}' and '{{ end_date }}'

🔥 Ce qu’il se passe si l’utilisateur passe une mauvaise date :

dbt run --vars '{start_date: "2024-13-01", end_date: "2024-12-31"}'

💥 Résultat :

Compilation Error in model fact_ventes:
🚨 La date '2024-13-01' n'est pas au format YYYY-MM-DD.

👉 dbt bloque immédiatement la compilation, ce qui évite d’envoyer un SQL invalide à la base.


✅ Avantages

AvantageDétail
🛑 Bloque tôtL’erreur est levée avant l’exécution SQL
🧼 PropreCentralise la logique de validation dans une macro
🔁 RéutilisablePeut être utilisée dans plusieurs modèles
🧠 Débogage plus clairLes messages sont explicites et orientés utilisateur
📦 Agnostique base de donnéesNe dépend pas de BigQuery, Snowflake, etc.

🧪 Astuce : tester avec dbt compile

dbt compile --vars '{"start_date": "2024-01-01", "end_date": "2023-01-01"}'

Tu verras l’erreur sans lancer de requête SQL.

Leave a Reply

Your email address will not be published. Required fields are marked *