12 min de lecturePar Camille Moreau

Data validation avec Great Expectations : le guide pragmatique

Comment des contrats de données ont réduit nos incidents de pipeline de 70 % — sans bureaucratie.

Les pipelines cassent en silence

Le pire incident de données n'est pas celui qui déclenche une alerte. C'est celui qui ne déclenche rien : une colonne renommée en amont, des valeurs nulles qui doublent, une devise passée d'euros à centimes. Le pipeline tourne, le dashboard s'affiche, et les chiffres sont simplement faux — pendant des semaines.

Chez nous, le déclic a été une baisse de 30 % du taux de conversion… qui était en réalité un bug de tracking. Deux semaines d'analyse pour comprendre que les données mentaient. Il fallait un garde-fou.

Le contrat de données, votre première ligne de défense

L'idée est simple : pour chaque table critique, on écrit noir sur blanc ce que les données promettent de respecter — et on vérifie ces promesses à chaque exécution du pipeline. Great Expectations (GX) fournit le vocabulaire :

  • Complétude : la colonne user_id n'est jamais nulle.
  • Unicité : pas deux lignes avec le même order_id.
  • Domaine de valeurs : country appartient à une liste fermée, amount est positif.
  • Distribution : le volume quotidien reste dans une fourchette plausible.

Mise en place pas à pas

Pas de big bang. Nous avons commencé par une seule table — celle dont dépend le reporting direction — avec cinq expectations, pas cinquante :

import great_expectations as gx

context = gx.get_context()
validator = context.sources.pandas_default.read_csv("orders.csv")

# Le contrat minimal qui aurait attrapé 90 % de nos incidents
validator.expect_column_values_to_not_be_null("order_id")
validator.expect_column_values_to_be_unique("order_id")
validator.expect_column_values_to_be_between("amount", min_value=0, max_value=100_000)
validator.expect_column_values_to_be_in_set("country", ["FR", "BE", "CH", "LU"])
validator.expect_table_row_count_to_be_between(min_value=10_000, max_value=2_000_000)

results = validator.validate()
if not results.success:
    notify_team(results)   # Slack + blocage du pipeline en amont

Trois principes ont fait la différence entre l'adoption et l'abandon :

  1. Peu de règles, mais justes. Chaque expectation doit correspondre à un incident réel ou redouté. Sinon elle finira ignorée.
  2. Bloquer tôt, alerter clairement. Une validation échouée stoppe le pipeline avant que les données ne se propagent, avec un message lisible par un humain pressé.
  3. Propriétaire identifié. Chaque contrat a un owner. Une alerte sans responsable est une alerte morte.

Piège classique

Ne validez pas « parce qu'on peut ». Une expectation qui échoue toutes les semaines sans conséquence apprend à l'équipe à ignorer toutes les alertes. Mieux vaut cinq règles respectées que cinquante contournées.

Résultats mesurés après six mois

IndicateurAvantAprès
Incidents de pipeline par mois~103
Temps moyen de détection3 jours< 1 heure
Incidents découverts par le métierla majorité0

Le bénéfice le plus précieux n'est pas dans le tableau : c'est la confiance. Quand les chiffres baissent maintenant, la première question n'est plus « les données sont-elles fiables ? » mais « que se passe-t-il vraiment ? ». C'est un tout autre métier.