Qu'est-ce qu'un contrat de données ? Une définition pratique
Ce qu'est un contrat de données, ce qu'il contient réellement, en quoi il diffère d'un schéma ou d'un SLA, et comment il est mis en application — avec un exemple ODCS complet.
· 9 min read
Un contrat de données est un accord explicite et versionné entre le producteur d'un jeu de données et ses consommateurs, qui précise ce que ce jeu de données garantit : son schéma, la signification de chaque champ, les attentes de qualité des données qu'il doit satisfaire, et les niveaux de service — fraîcheur, disponibilité, support — sous lesquels il est livré. Il s'écrit sous la forme d'un document lisible par une machine, stocké dans le gestionnaire de versions aux côtés du code, relu via des pull requests, et appliqué automatiquement en exécutant ses attentes de qualité sur les données réelles. Un contrat est une promesse portant sur une interface, pas la description d'un pipeline.
Le mot « contrat » n'est pas là pour faire joli dans cette définition. Il suppose deux parties nommées, une obligation énoncée, une version que l'on peut désigner, et des conséquences lorsque l'obligation n'est pas tenue. Un fichier de schéma ne possède aucune de ces propriétés ; un contrat les possède toutes les quatre.
Pourquoi les contrats de données sont apparus
Trois modes de défaillance ont conduit les équipes à cette idée, et il vaut la peine de les nommer, car ils expliquent la forme de la solution.
La dérive de schéma sans notification. Une équipe productrice renomme une colonne, élargit un type ou supprime un champ qu'elle croit inutilisé. Le changement passe ses tests, parce que ses tests couvrent son code. En aval, un tableau de bord casse, un modèle se réentraîne silencieusement sur des valeurs nulles, ou un traitement nocturne échoue à 03:00. Il n'y avait pas d'interface, donc rien à casser — seulement une table qui a changé.
Des tableaux de bord cassés sans propriétaire responsable. Quand la qualité se dégrade, la conversation commence par de l'archéologie. Qui produit cette table ? Que devait-elle contenir ? Est-ce que 4 % de valeurs nulles sur customer_id, c'était normal depuis toujours ? Personne ne l'a consigné, la réponse prend donc une semaine, et le correctif se fait en aval plutôt qu'en amont.
Le couplage entre producteur et consommateur. Sans interface énoncée, les consommateurs font de la rétro-ingénierie sur l'implémentation du producteur — ils lisent des tables intermédiaires, dépendent d'ordres de tri accidentels, codent en dur des hypothèses sur les valeurs d'un champ de statut. Chacune de ces pratiques devient une obligation non écrite dont le producteur ignore l'existence.
L'industrie logicielle a résolu le problème analogue avec les contrats d'API : spécifications OpenAPI, versionnage sémantique, fenêtres de dépréciation. Un contrat de données applique la même discipline à l'interface de données. L'idée centrale est que la promesse elle-même devient un artefact, distinct du pipeline qui la réalise et distinct de l'outil qui la vérifie.
Ce que contient un contrat de données
Un contrat complet porte cinq choses.
- Identité et propriété. Ce qu'est le jeu de données, quelle équipe le possède, comment la joindre, quelle est la version du contrat lui-même. La propriété n'est pas décorative : c'est la partie qui se tient de l'autre côté de l'accord.
- Schéma et sémantique. Les champs, leurs types (logiques et physiques), leur caractère obligatoire ou non, et — point crucial — ce que chacun signifie.
amountn'est pas une description ; « total de la commande en EUR, hors TVA, après remises » en est une. - Attentes de qualité. Les règles que les données doivent satisfaire, chacune avec un seuil et une sévérité : les colonnes obligatoires ne sont jamais nulles, les clés sont uniques, les champs catégoriels restent dans un ensemble autorisé, les nombres restent dans une plage plausible, les clés étrangères se résolvent.
- Niveaux de service. La fraîcheur (à quel point la mise à jour des données doit être récente), la disponibilité, la rétention, et les attentes de support qui les accompagnent.
- Politique de changement. Comment le contrat est versionné, ce qui constitue une rupture de compatibilité, et le préavis dont bénéficient les consommateurs avant qu'un changement cassant n'arrive.
Voici la forme que cela prend en pratique, rédigée dans l'Open Data Contract Standard :
apiVersion: v3.0.0
kind: DataContract
info:
title: orders
version: 2.1.0
owner: data-platform
schema:
- name: orders
physicalName: orders
physicalType: table
properties:
- name: order_id
logicalType: string
physicalType: uuid
required: true
primaryKey: true
description: Business key, stable across restatements.
quality:
- rule: nullCount
dimension: completeness
severity: error
mustBe: "0"
- rule: duplicateCount
dimension: uniqueness
severity: error
mustBe: "0"
- name: status
logicalType: string
description: Lifecycle state. New values require a minor version bump.
quality:
- rule: validValues
dimension: conformity
severity: error
mustBe: "['pending', 'paid', 'shipped', 'refunded']"
- name: total_amount
logicalType: number
physicalType: numeric
description: Order total in EUR, excluding VAT, after discounts.
quality:
- rule: between
dimension: accuracy
severity: error
mustBe: "[0, 100000]"
- name: created_at
logicalType: timestamp
quality:
- rule: freshness
dimension: timeliness
severity: error
mustBe: "<= 24h"
Lisez-le comme une phrase : l'équipe data-platform promet une table nommée orders, dont l'order_id est toujours présent et unique, dont le status prend exactement l'une de quatre valeurs, dont le total_amount est un montant en euros compris entre zéro et cent mille, et qui n'a jamais plus de 24 heures d'ancienneté. Cette phrase, c'est le contrat. Tout le reste n'est que syntaxe.
Contrats, schémas et SLA
Les trois sont souvent confondus, et les différences font tout l'intérêt de la distinction.
| Contrat de données | Schéma | SLA | |
|---|---|---|---|
| Énonce | Structure, sens, qualité et niveaux de service | Structure et types uniquement | Objectifs de disponibilité et d'actualité |
| Comporte deux parties | Oui — producteur et consommateurs nommés | Non | Généralement |
| Versionné comme un artefact | Oui, sémantiquement, dans git | Parfois | Rarement |
| Applicable par une machine | Oui, par un moteur de validation | Partiellement, à l'écriture | Mesuré, pas appliqué |
| Couvre la sémantique | Oui | Non | Non |
Un schéma vous dit qu'une colonne est une string. Un contrat vous dit que c'est un code devise, qu'il fait toujours partie des valeurs ISO 4217 que vous acceptez, qu'il n'est jamais nul, et que l'équipe paiements en est responsable. Un SLA vous dit que la table se rafraîchit quotidiennement ; un contrat énonce cela et ce qui doit être vrai des lignes qu'elle contient.
En somme : un schéma est un sous-ensemble d'un contrat, et un SLA est un sous-ensemble d'un contrat. Le contrat est l'artefact qui rend les deux relisibles au même endroit.
Comment un contrat est mis en application
Un contrat que personne ne vérifie est un document, pas un accord. L'application se joue à trois moments.
Au moment de la relecture. Comme le contrat est un fichier, une modification est un diff dans une pull request, avec un auteur et une raison. C'est la propriété la plus précieuse et la moins commentée des contrats de données : quelqu'un peut contester un seuil avant sa fusion. Une règle assouplie dans l'interface d'un éditeur ne laisse aucune trace permettant de savoir si le métier a changé ou si quelqu'un en avait assez de l'alerte.
Au moment de l'exécution. Un moteur d'exécution compile chaque attente de qualité en une requête sur le jeu de données réel et consigne le résultat. nullCount devient un COUNT(*) WHERE col IS NULL ; freshness devient une comparaison à now(). C'est de la validation des données ordinaire — le contrat est simplement l'endroit où les attentes sont déclarées, au lieu d'être éparpillées dans des scripts, et le guide de la validation des données explique comment ces requêtes s'écrivent, se planifient et se dotent de seuils en pratique. La sévérité décide de la conséquence : error bloque ou alerte, warning enregistre une tendance.
Au moment du changement. Le versionnage sémantique du contrat porte le sens. Un patch assouplit ou resserre un seuil ; une version mineure ajoute une colonne ou une règle, de manière additive ; une version majeure supprime ou renomme un champ, change un type, ou se met à rejeter des données jusque-là acceptées. C'est la version qui permet à un consommateur de décider si un changement le concerne, sans lire le diff.
Catalyst met en œuvre exactement cette boucle : les contrats sont du YAML ODCS, le fichier faisant foi ; les règles se compilent en SQL natif pour PostgreSQL, BigQuery, SQL Server et d'autres ; et les résultats se consolident par dimension de qualité, de sorte que les trous de couverture sont visibles plutôt que sous-entendus.
Par où commencer
Ne commencez pas par tout mettre sous contrat. Choisissez un jeu de données qui a cassé quelque chose récemment et dont le propriétaire est identifiable, écrivez ce qu'il promet déjà implicitement, et faites valider cela par le producteur. Importez le schéma depuis la base plutôt que de le saisir — un brouillon généré de trente règles que vous élaguez ensuite est un bien meilleur point de départ qu'un fichier vide.
Le premier contrat est un exercice de documentation. C'est au deuxième que la discipline commence à payer, parce qu'entre-temps quelqu'un aura tenté un changement cassant et que le contrat l'aura attrapé.
Questions fréquentes
Qu'est-ce qu'un contrat de données, en termes simples ?
Un contrat de données est un accord écrit et versionné sur ce qu'un jeu de données garantit : quels champs il contient, ce qu'ils signifient, quelles règles de qualité ils doivent satisfaire, et à quel point les données seront fraîches. Il est stocké dans le gestionnaire de versions comme du code, relu en pull request, et vérifié automatiquement sur les données réelles.
Quelle est la différence entre un contrat de données et un schéma ?
Un schéma décrit une structure : noms et types de champs. Un contrat de données englobe le schéma mais y ajoute ce qu'un schéma ne peut pas exprimer : ce que chaque champ signifie, les règles de qualité que les valeurs doivent satisfaire, les niveaux de service en matière de fraîcheur et de disponibilité, le propriétaire responsable, et une politique de versionnage qui définit ce qui constitue un changement cassant.
Contrats de données et ODCS, est-ce la même chose ?
Non. « Contrat de données » est le concept — une promesse convenue et versionnée entre un producteur et ses consommateurs. ODCS, l'Open Data Contract Standard, est un format ouvert et indépendant des éditeurs permettant de consigner cette promesse en YAML. Vous pouvez avoir des contrats de données dans un format maison ; c'est l'usage d'un standard ouvert qui les garde portables d'un outil à l'autre.
Comment un contrat de données est-il appliqué ?
En compilant ses attentes de qualité en requêtes qui s'exécutent sur le jeu de données réel selon une planification, et en relisant les modifications du contrat lui-même comme des pull requests. Les règles portent une sévérité : une violation bloque donc la consommation en aval ou se consigne comme une tendance d'avertissement. L'application, c'est de la validation des données ordinaire ; le contrat n'est que l'endroit où les attentes sont déclarées.
Qui écrit le contrat de données, le producteur ou le consommateur ?
Le producteur en est propriétaire, puisque c'est lui qui fait la promesse — mais le premier brouillon se négocie généralement, car ce sont les consommateurs qui savent de quelles garanties ils dépendent réellement. Un contrat écrit par les seuls consommateurs est une liste de souhaits ; un contrat écrit par les seuls producteurs a tendance à ne promettre que ce qui est déjà facile.