Les données en retard sont la raison pour laquelle les modèles incrémentaux dérivent de la vérité source. Un enregistrement avec un timestamp d’événement du 20 mars arrive dans votre entrepôt le 24 mars. Votre modèle a traité les données du 20 mars trois jours plus tôt et est passé à autre chose. Sans stratégie pour rattraper les arrivées tardives, cet enregistrement est manqué définitivement, et l’écart entre votre modèle et la vérité source se creuse à chaque exécution.
Ce hub relie les concepts nécessaires pour gérer correctement les données en retard dans dbt.
Le problème fondamental
Deux timestamps pilotent le problème : l’heure d’événement (quand quelque chose s’est produit) et l’heure de chargement (quand l’enregistrement a atteint votre entrepôt). Les filtres incrémentaux standard regardent uniquement l’heure de chargement ou le timestamp d’événement maximum — ils manquent les enregistrements arrivés tardivement par rapport à la dernière exécution du modèle.
-- Ceci manque les données en retard{% if is_incremental() %}WHERE event_date > (SELECT MAX(event_date) FROM {{ this }}){% endif %}Si ce modèle s’est exécuté le 15 janvier et a capturé des événements jusqu’au 14 janvier, tous les événements du 13 janvier arrivant aujourd’hui sont entièrement ignorés.
Commencer par mesurer
Avant de choisir une stratégie, mesurez le profil de latence réel de vos données. La distribution des délais d’arrivée détermine quels patterns sont pertinents et quelle taille de fenêtre est appropriée.
→ Mesurer la latence des données avant de choisir une stratégie incrémentale
La fenêtre de lookback
La défense standard : retraiter une fenêtre glissante de données récentes à chaque exécution. Au lieu de filtrer uniquement les nouvelles données, soustrayez une fenêtre fixe du maximum actuel et retraitez tout à partir de là.
Rendez-la configurable pour pouvoir étendre la fenêtre lors des backfills sans modifier le code du modèle :
{% set lookback_days = var('lookback_days', 3) %}
{% if is_incremental() %}WHERE event_date >= ( SELECT DATE_SUB(MAX(event_date), INTERVAL {{ lookback_days }} DAY) FROM {{ this }}){% endif %}→ Données en retard et le pattern de fenêtre de lookback
Limiter les scans de destination avec les prédicats incrémentaux
Sur les grandes tables, la fenêtre de lookback filtre les données source mais le merge scanne toujours la table de destination entière. Les prédicats incrémentaux contraignent le scan de destination à la même fenêtre, maintenant la viabilité du merge à grande échelle.
→ Prédicats incrémentaux pour le merge dbt
Stratégies basées sur les partitions
Pour les tables partitionnées par date, remplacer des partitions entières est souvent plus efficace que le merge ligne par ligne. L’approche correcte diffère selon l’entrepôt :
- BigQuery :
insert_overwriteavec une liste de partitions statique - Snowflake :
delete+insertavec des prédicats de date (pasinsert_overwrite— cela remplace toute la table) - Databricks :
replace_whereavec une expression de prédicat
Chacune a un angle mort : les enregistrements arrivant après la fermeture de la fenêtre de remplacement de leur partition sont manqués définitivement sans full refresh ou fenêtre plus longue.
→ Patterns de configuration des stratégies incrémentales dbt → Comportements des stratégies incrémentales dbt par entrepôt → Cadre de décision pour les stratégies incrémentales
Déduplication et idempotence
Une fenêtre de lookback signifie traiter les mêmes enregistrements plusieurs fois. Votre modèle doit produire des résultats identiques quel que soit le nombre de fois qu’il s’exécute. Se fier uniquement à unique_key n’est pas suffisant — le full refresh initial n’applique pas la logique de merge. Ajoutez une déduplication explicite dans votre SELECT :
QUALIFY ROW_NUMBER() OVER ( PARTITION BY event_id ORDER BY _loaded_at DESC) = 1Lorsque l’unicité s’étend sur plusieurs colonnes, utilisez generate_surrogate_key de dbt-utils pour créer une clé unique stable.
→ Modèles incrémentaux idempotents dans dbt → generate_surrogate_key de dbt-utils
Tester la gestion des données en retard
Les tests unitaires dbt (1.8+) peuvent simuler des arrivées tardives en remplaçant is_incremental() et en fournissant des lignes de fixture pour {{ this }}. En production, comparez les résultats incrémentaux à une baseline de full refresh pour détecter les dérives.
→ Tester la gestion des données en retard dans dbt
Le filet de sécurité du full refresh
Aucune fenêtre de lookback ne capture tout. Les données peuvent arriver avec un retard arbitraire. La config full_refresh: false empêche les reconstructions accidentelles de plusieurs heures tout en gardant les full refreshes intentionnels possibles. Planifiez des full refreshes périodiques pour réinitialiser la dérive accumulée.
→ Le garde-fou full_refresh: false dans dbt
Microbatch comme alternative
La stratégie microbatch de dbt (1.9+) dispose d’un support de lookback intégré via le paramètre de config lookback. Elle gère automatiquement le filtrage sans logique is_incremental(), et fournit une relance au niveau du batch pour les périodes en échec. Compromis : taille de batch minimum horaire, tous les calculs de temps utilisent UTC, et les batches s’exécutent séquentiellement.
→ Compromis de la stratégie microbatch de dbt
Article source
→ Données en retard dans dbt : des patterns qui fonctionnent vraiment