dbt: Freshness


🧠 Contexte

Tu déclares une source dans dbt (par exemple : une table dans ton data warehouse), et tu veux surveiller si elle est fraîche, c’est-à-dire :

  • qu’elle a bien été mise à jour récemment
  • qu’elle respecte une fréquence d’alimentation attendue

Mais parfois, une même source est alimentée par plusieurs pipelines différents :

Exemple de table sourceProcessus de chargementFréquence
raw.transactionsingestion par API temps réeltoutes les 15 minutes
batch de consolidation backend1 fois par heure

🎯 Problème : une seule définition freshness standard ne suffit pas

Si tu fais simplement :

freshness:
  error_after: { count: 30, period: minute }
  warn_after: { count: 15, period: minute }

→ Tu appliques une règle unique à une source potentiellement multi-origine. Tu risques :

  • soit de déclencher des alertes inutiles,
  • soit de ne pas détecter le vrai problème (ex : si la partie “batch” est en retard mais que les données arrivent toujours côté API).

✅ Solution : plusieurs blocs freshness avec critères différents

dbt permet de configurer plusieurs règles de fraîcheur (avec condition), dans une même source, pour mieux refléter la réalité métier.

⚠️ Attention : dbt ne supporte pas nativement plusieurs blocs freshness par source, mais tu peux contourner cela intelligemment en :

  • créant plusieurs tables source logiques qui pointent vers la même table physique
  • ou en utilisant une macro customisée pour la validation conditionnelle selon l’heure, la partition ou l’environnement

🔧 Exemple 1 : définir deux sources logiques pour la même table physique

version: 2

sources:
  - name: app_sources
    schema: raw
    tables:
      - name: transactions_api
        identifier: transactions
        freshness:
          warn_after: { count: 15, period: minute }
          error_after: { count: 30, period: minute }
        loaded_at_field: updated_at
        meta:
          origin: api

      - name: transactions_batch
        identifier: transactions
        freshness:
          warn_after: { count: 1, period: hour }
          error_after: { count: 2, period: hour }
        loaded_at_field: updated_at
        meta:
          origin: batch

➡️ Tu déclares deux entrées source, mais elles pointent vers la même table transactions dans le warehouse.


🧪 Tu peux ensuite surveiller chaque “flux” :

dbt source freshness --select source:app_sources.transactions_api
dbt source freshness --select source:app_sources.transactions_batch

🧩 Exemple 2 : logique conditionnelle dans une macro

Si tu veux une logique dépendante de l’heure (ex : tolérance plus large la nuit), tu peux créer un test personnalisé ou une macro :

{% macro validate_transactions_freshness(source_name, max_delay_minutes) %}
  {% set now = modules.datetime.datetime.now() %}
  {% set allowed_delay = modules.datetime.timedelta(minutes=max_delay_minutes) %}
  {% set freshness = ... %}  {# lire le MAX(updated_at) #}
  {% if now - freshness > allowed_delay %}
    {{ exceptions.raise_compiler_error("Freshness check failed for " ~ source_name) }}
  {% endif %}
{% endmacro %}

Et tu appelles cette macro via un dbt run-operation.


✅ Avantages de cette stratégie

BénéficeDétail
🎯 Suivi précis de chaque flux de chargementTu sais si l’API ou le batch est en retard
🧩 Une seule définition source réutilisableTu gardes la maintenance facile
🔁 Flexibilité horaire ou métierTu peux adapter la règle à l’heure, au type, à l’env…
🛑 Moins de fausses alertesChaque flux a sa propre tolérance de délai

🧠 Résumé

ÉlémentExplication
freshness:Permet de vérifier si une table source est à jour
Cas multi-fluxTu dois surveiller chaque logique de chargement individuellement
Solution 1Déclarer plusieurs entrées source avec identifier commun
Solution 2Utiliser une macro conditionnelle ou personnalisée
AvantageMonitoring plus fin, détection plus fiable des incidents

Leave a Reply

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