Un pipeline qui casse en production, c’est souvent la faute d’un changement non communiqué en amont. Le data contract est la solution pragmatique: un fichier de config versionné qui agit comme une API pour vos données. Il force producteur et consommateur à se mettre d’accord et automatise la validation. Fini les surprises, on fiabilise la chaîne.
prérequis
- Un propriétaire (owner) de la donnée clairement identifié.
- Une CI/CD fonctionnelle pour automatiser les checks.
- Un endroit pour stocker les contrats (un repo Git fait l’affaire).
aperçu rapide
- Le problème: Les schémas de données changent sans prévenir et cassent tout en aval.
- La solution: Un contrat formel (souvent un fichier YAML) qui décrit la structure de la donnée.
- Le principe: Le contrat est validé automatiquement dans la CI. Pas de contrat respecté, pas de déploiement.
- Les évolutions: Changement mineur (ajout) -> OK. Changement majeur (suppression/renommage) -> nouvelle version du contrat.
- Le gain: Moins d’incidents, plus de confiance entre les équipes.
tutoriel pas-à-pas
étape 1: Écrire le contrat
C’est juste un fichier de config. Placez-le avec le code du producteur de la donnée.
# contracts/produit/events_v1.yml
contract_id: produit.events_v1
version: 1.2.0
owner: team-backend
schema:
- name: event_id
type: string
- name: event_timestamp
type: timestamp
- name: user_id
type: string
- name: event_name
type: string
# 'backward' = seuls les ajouts sont permis
compatibility_level: backward
deprecation_days: 30
étape 2: Valider en CI
Le contrat doit être testé à chaque commit du producteur. Si la donnée produite ne matche pas le contrat, la CI doit échouer.
# Commande simple dans un pipeline de CI/CD
# Ce script compare le schéma de la table/vue de prod avec le contrat YAML
python tests/check_contract.py --table produit.events_v1 --contract contracts/produit/events_v1.yml
étape 3: Gérer les changements
Le versioning est la clé.
- Mineur:
ALTER TABLE ... ADD COLUMN ...-> Mettre à jour le contrat, la version ne bouge pas. - Majeur:
ALTER TABLE ... RENAME COLUMN ...-> Interdit. Il faut créerevents_v2.ymlet laisser l’ancienne version active le temps de la migration (cf.deprecation_days).
exemples complets
cas 1: Ajouter un champ device
L’équipe produit veut tracer l’appareil. C’est un ajout, donc pas de risque.
- Quoi: Une nouvelle colonne nullable
device. - Pourquoi: C’est rétrocompatible. Les consommateurs qui ne connaissent pas ce champ l’ignoreront.
- Code:
-- Le producteur ajoute la colonne à sa table source
ALTER TABLE produit.events ADD COLUMN device STRING;
-- La vue v1 exposée aux consommateurs est mise à jour
CREATE OR REPLACE VIEW produit.events_v1 AS
SELECT event_id, event_timestamp, user_id, event_name, device FROM produit.events;
erreurs courantes et solutions
-
Symptôme: Un dashboard est cassé.
- Cause: Quelqu’un a renommé une colonne en pensant que “c’était mieux”.
- Correctif: Le contrat l’aurait forcé à créer une v2, rendant le changement explicite et non-cassant.
-
Symptôme: Les IDs sont passés de
intàstring.- Cause: Un changement de logique applicative a été répercuté en base sans mesurer l’impact.
- Correctif: Les tests de type du contrat dans la CI auraient immédiatement échoué.
-
Symptôme: En cas de problème, personne ne sait qui appeler.
- Cause: Ownership flou.
- Correctif: Le champ
ownerdans le contrat. C’est simple, mais ça change tout.
faq
-
C’est lourd à maintenir, non ? Moins lourd qu’un incident à 3h du matin. La rigueur initiale est rentabilisée très vite.
-
Pourquoi ne pas juste utiliser des tests dbt ? Les tests dbt valident un état. Le contrat est une promesse sur le futur. C’est un outil de communication et de gouvernance avant d’être un outil de test.