Valider une migration dbt nécessite de prouver que le nouveau système produit les mêmes résultats que l’ancien. L’approche recommandée est l’exécution parallèle — faire tourner les deux systèmes sur les mêmes données sources — avec trois niveaux de comparaison par modèle. L’objectif est des sorties identiques, de façon prouvable.
Mise en place de l’exécution parallèle
Gardez votre système existant (Dataform, ancien projet dbt ou ce depuis quoi vous migrez) en fonctionnement pendant la construction du remplacement. Configurez le nouveau projet dbt pour écrire dans un dataset séparé afin que les deux systèmes produisent des sorties à partir des mêmes données sources :
models: my_project: +schema: dbt_migration_validationCela crée un miroir de vos sorties de production dans un dataset de validation. Les deux systèmes lisent les mêmes sources. Les deux produisent les mêmes modèles. La seule différence devrait être le nom du dataset.
Faites tourner les deux systèmes sur le même calendrier pendant au moins deux semaines. Une semaine détecte la plupart des problèmes. Deux semaines détecte les cas limites autour des patterns hebdomadaires, des frontières de mois et des données du week-end qui se comportent différemment des données en semaine.
Requêtes de comparaison
Pour chaque modèle migré, exécutez trois niveaux de validation.
Niveau 1 : Comptages de lignes
La vérification la plus basique. Si les comptages de lignes diffèrent, quelque chose est fondamentalement erroné.
SELECT 'old_system' AS source, COUNT(*) AS row_countFROM old_dataset.model_nameUNION ALLSELECT 'new_dbt' AS source, COUNT(*) AS row_countFROM dbt_migration_validation.model_name;Les divergences de comptage de lignes se tracent généralement vers :
- Une logique de déduplication différente (notamment dans les modèles incrémentaux)
- Des conditions de filtre mal traduites
- Des déclarations de sources pointant vers des tables légèrement différentes
- Des différences de gestion des fuseaux horaires qui déplacent des enregistrements au-delà des frontières de date
Niveau 2 : Métriques agrégées
Les comptages de lignes correspondent, mais les chiffres s’additionnent-ils ? Comparez les métriques métier clés :
SELECT ABS(old.total_revenue - new.total_revenue) AS revenue_diff, ABS(old.order_count - new.order_count) AS order_diff, ABS(old.avg_order_value - new.avg_order_value) AS aov_diffFROM ( SELECT SUM(revenue) AS total_revenue, COUNT(*) AS order_count, AVG(revenue) AS avg_order_value FROM old_dataset.orders) oldCROSS JOIN ( SELECT SUM(revenue) AS total_revenue, COUNT(*) AS order_count, AVG(revenue) AS avg_order_value FROM dbt_migration_validation.orders) new;Les différences agrégées sans différences de comptage de lignes pointent vers :
- Des changements de précision numérique (particulièrement pertinents lors de la conversion d’arithmétique JavaScript en Jinja)
- Des différences de gestion des NULL dans les calculs SUM/AVG
- Un arrondi appliqué à des étapes différentes
Niveau 3 : Comparaison ligne par ligne
La vérification la plus approfondie. Utilisez dbt-audit-helper ou des requêtes EXCEPT manuelles pour trouver les différences exactes au niveau des lignes :
-- Trouver les lignes dans l'ancien qui ne sont pas dans le nouveauSELECT * FROM old_dataset.model_nameEXCEPT DISTINCTSELECT * FROM dbt_migration_validation.model_name;
-- Trouver les lignes dans le nouveau qui ne sont pas dans l'ancienSELECT * FROM dbt_migration_validation.model_nameEXCEPT DISTINCTSELECT * FROM old_dataset.model_name;Pour les tables avec de nombreuses colonnes, EXCEPT DISTINCT est coûteux mais définitif. Pour une comparaison ciblée, choisissez la clé primaire plus les colonnes les plus susceptibles de diverger (champs calculés, agrégations, timestamps).
Le package dbt-audit-helper fournit les macros compare_relations et compare_column_values qui automatisent ce pattern et produisent des statistiques récapitulatives.
Tests de régression des pipelines ML
Si des modèles de machine learning consomment vos sorties de transformation, la comparaison standard ligne par ligne est nécessaire mais insuffisante. Les modèles ML sont sensibles aux changements qui semblent triviaux dans une comparaison de données.
L’histoire cautionniaire : une équipe a constaté que les comportements de template JavaScript et Jinja différaient de façons qui ont cassé le ré-entraînement du modèle de détection de fraude. La précision numérique, la gestion des nulls et le formatage des timestamps ont divergé de façons subtiles qui n’apparaissaient pas dans les comparaisons agrégées mais décalaient suffisamment les distributions des features pour dégrader les performances du modèle.
Exécutez le pipeline d’entraînement ML sur les sorties dbt avant de finaliser la migration. Comparez :
- Les métriques de performance du modèle (accuracy, precision, recall, AUC) entre l’entraînement sur les anciennes et nouvelles données
- Les statistiques de distribution des features (moyenne, médiane, écart-type, percentiles) pour chaque feature d’entrée
- Les distributions de prédiction sur un ensemble de test réservé
Si les métriques de performance se décalent de plus de votre tolérance acceptable (typiquement 1-2 % pour la plupart des modèles en production), investiguez les différences au niveau des features pour trouver la cause racine.
Ces tests ajoutent du temps à la migration. Ils préviennent aussi le scénario où vous déclarez la migration terminée, retirez l’ancien système, et découvrez trois semaines plus tard que les performances du modèle se sont dégradées parce qu’un seuil de clause WHERE générée s’est décalé de 0,0001.
Stratégie de basculement par phases
Ne migrez pas tout en une seule fois. Travaillez en phases :
Phase 1 : Modèles de base. Convertissez d’abord les déclarations de sources et les modèles de base. Ce sont des conversions mécaniques avec des critères de validation clairs. Exécutez les comparaisons. Corrigez les divergences.
Phase 2 : Modèles intermédiaires. Convertissez les jointures et la logique métier. C’est là que se cachent la plupart des bugs. Validez attentivement les métriques agrégées.
Phase 3 : Modèles marts. Convertissez les tables orientées consommateurs en dernier. Ce sont celles que voient réellement les parties prenantes, donc les différences ici sont les plus visibles.
Phase 4 : Basculement. Pointez les consommateurs en aval (outils BI, reverse ETL, pipelines ML) vers les nouveaux datasets un par un. Gardez l’ancien système en fonctionnement pendant encore au moins une semaine comme option de rollback.
Chaque phase devrait avoir des critères d’approbation explicites : les comptages de lignes correspondent, les métriques agrégées correspondent dans les tolérances, et pas de différences au niveau des lignes au-delà de l’arrondi attendu.
Quand « suffisamment proche » est la bonne réponse
L’équivalence parfaite est parfois impossible. L’arithmétique en virgule flottante, la gestion des fuseaux horaires et la propagation des NULL peuvent créer des différences qui sont techniquement correctes dans les deux systèmes mais produisent des résultats différents.
Documentez ces différences connues. Si l’ancien système arrondit à l’étape 3 et le nouveau à l’étape 5, les valeurs finales peuvent différer d’une fraction de centime. C’est acceptable si les parties prenantes sont d’accord. Ce qui n’est pas acceptable, ce sont des différences non documentées qui surgissent comme « les chiffres ont changé » après le basculement.
Créez un journal de validation de migration — un document listant chaque modèle, son statut de validation, les différences connues, et la validation du propriétaire du modèle. Cela devient votre piste d’audit et votre référence de rollback si quelque chose surgit après la migration.