Refactorer une modélisation legacy avec dbt

La dette technique SQL, on la connaît tous :

  • des vues imbriquées sur 7 niveaux
  • des procédures stockées écrites à 4 mains, non versionnées
  • des logiques métiers encapsulées dans des sous-requêtes sans nom
  • aucun test, aucune documentation, aucune visibilité

🎯 L’objectif ? Basculer progressivement ce spaghetti SQL dans une architecture claire, modulaire et gouvernée avec un outil moderne, comme par exemple dbt.


🧭 Étape 1 – Comprendre le legacy

Avant de toucher à une ligne de code :

  • on importe sous dbt notre amas SQL dans un dossier « models » afin de pouvoir s’y référer
  • on identifie les sources afin de les déclarer comme tel et rendre le lineage plus lisible
  • on mappe les dépendances entre objets (vue A appelle B qui appelle C… le brouillon du futur DAG)
  • on identifie les tables finales réellement utilisées par les consommateurs
  • on repère les tables pivot (clients, contrats, transactions…)

📌 Astuce : un petit EXPLAIN bien placé permet d’identifier rapidement la hiérarchie d’appels


🧪 Étape 2 – Choix de la stratégie de refactoring

2 stratégies sont possibles:

  • in-place refactoring: travailler directement sur le sql legacy que nous avons importé
  • alongside refactoring: travailler sur un répertoire dédié le nouveau modèle

dbt préconise de façon assez évidente la seconde stratégie: moins d’impacte sur l’utilisateur final, plus simple à auditer, lisibilité dans git etc…

On découpe alors notre nouveau modèle comme suit :

  • stg_ pour les données brutes nettoyées
  • int_ pour la logique métier (calculs, règles, mappings)
  • mart_ pour les données prêtes à être consommées (dashboards, reporting)

➡️ Exemple :

-- stg_transaction.sql
select id, date_tx, montant_tx

from source_legacy.transactions

-- int_client_revenus.sql
select id_client, sum(montant_tx) as revenu_12m

from {{ ref('stg_transaction') }}
group by id_client

-- mart_clients_segments.sql
select c.id_client, c.segment, r.revenu_12m
from {{ ref('stg_clients') }} c
left join {{ ref('int_client_revenus') }} r using(id_client)

💡 Si une logique métier est trop obscure, on la factorise en macro ou on y met des commentaires clairs. L’objectif est de rendre le code le plus modulaire possible.


🧼 Étape 3 – Structurer le contenu de nos modèles

Une fois les modèles définis, il s’agit de structurer leur contenu. dbt propose le pattern suivant:

Ré-écrire sous forme de CTEs les requêtes:

  • les CTE ‘Import’ -> on importe les modèles déjà existants
  • les CTE ‘Logique’ -> on intègre une logique métier, des champs calculés, etc..
  • une CTE ‘Finale’ -> la vue finale
  • On termine l’écriture du modèle par un simple select * de notre CTE finale

📚 Étape 4 – Tester et Documenter

Une fois la chaîne reconstituée :

  • on gère les tests automatiquement via les generic tests (not null, unique, relationship)
  • on utilise exposures pour lier les dashboards Tableau/Power BI aux modèles
  • on publie une documentation automatique avec dbt docs generate
  • on ajoute des tags pour filtrer les modèles par usage : #marketing, #finance, #audit, etc.

🧘 Étape 5 – Migration progressive

Plutôt que de tout basculer d’un coup :

  1. On recrée les flux critiques dans dbt
  2. On compare les résultats avec les tables legacy (minus, except)
  3. On décommissionne par lots si besoin

📎 Le guide officiel de dbt ➡️
https://docs.getdbt.com/guides/refactoring-legacy-sql?step=1


💡 Migrer un legacy SQL vers dbt, c’est transformer un enchevêtrement de vues SQL en une architecture modulaire, testée et gouvernée.
Le fond reste le même, mais tout devient plus clair, plus fiable, plus scalable.

#dbt #SQL #AnalyticsEngineering #DataRefactoring #ModernDataStack #DataModelling #BusinessDataAnalyst #DataQuality #GouvernanceDesDonnées #DataOps

Laisser un commentaire

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

Retour en haut