Qu'est-ce qu'ODCS ? L'Open Data Contract Standard, expliqué
Ce qu'est l'Open Data Contract Standard, ce que contient réellement un contrat v3, pourquoi un standard ouvert vaut mieux que le format de règles d'un éditeur, et comment l'import et l'export ODCS gardent vos règles de qualité des données portables.
· 9 min read
L'Open Data Contract Standard (ODCS) est une spécification ouverte permettant de décrire ce qu'un jeu de données promet : son schéma, son propriétaire, ses niveaux de service et — la partie qui intéresse le plus les équipes — ses règles de qualité des données. C'est un document YAML, versionné comme du code, lisible par un humain et exécutable par un outil. ODCS est développé de manière ouverte au sein du projet Bitol, sous l'égide AI & Data de la Linux Foundation, ce qui signifie qu'aucun éditeur ne le contrôle et qu'aucun éditeur ne peut prendre vos règles en otage.
Le problème qu'il résout
Chaque outil de qualité des données invente son propre format de règles. dbt a ses tests dans un schema.yml. Great Expectations a ses suites d'attentes en JSON. Soda a SodaCL. Monte Carlo a ses moniteurs dans son interface. Chaque format est raisonnable pris isolément, et aucun ne voyage.
Cela a trois conséquences pratiques :
- Vos attentes sont liées à un moteur d'exécution. Passer d'un outil à un autre suppose de réécrire chaque règle à la main — c'est pour cela que les équipes ne changent pas d'outil, et c'est pour cela que le format conserve son public captif.
- Producteurs et consommateurs ne s'accordent pas sur ce qui a été promis. Les règles vivent dans le dépôt du pipeline, dans le format de l'équipe du pipeline. L'équipe analytique qui dépend de la table ne peut pas les lire, et encore moins relire un changement.
- Rien n'est relisible. Une règle modifiée dans l'interface d'un éditeur ne laisse aucun diff. Savoir si le seuil a bougé parce que le métier a changé ou parce que quelqu'un en avait assez de l'alerte devient impossible.
Un contrat de données répond à ces trois points en faisant de la promesse elle-même l'artefact — distinct de l'outil qui l'applique, versionné dans le même dépôt que tout le reste, et écrit dans un format que les deux côtés de l'interface peuvent lire.
Ce que contient réellement un contrat ODCS
Un contrat v3 est un document YAML comportant un petit nombre de blocs de premier niveau. L'essentiel :
apiVersion: v3.0.0
kind: DataContract
info:
title: orders
version: 1.2.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
quality:
- rule: validValues
dimension: conformity
severity: error
mustBe: "['pending', 'paid', 'shipped', 'refunded']"
- name: created_at
logicalType: timestamp
quality:
- rule: freshness
dimension: timeliness
severity: error
mustBe: "<= 24h"
quality:
- rule: rowCount
dimension: consistency
severity: warning
mustBe: "> 0"
En le lisant de haut en bas :
apiVersionetkindidentifient le document comme un contrat de données ODCS v3. Les outils s'en servent pour décider s'ils peuvent seulement l'analyser.infoporte les métadonnées destinées aux humains — titre, version sémantique, propriétaire. La version est celle du contrat, pas celle des données, et c'est elle qui indique à un consommateur si un changement était additif ou cassant.schemadécrit les objets physiques. Lespropertiessont les colonnes, avec à la fois unlogicalType(portable : string, number, timestamp) et unphysicalType(celui du moteur :uuid,NUMERIC,datetime2). Conserver les deux est ce qui permet à un même contrat de décrire le même jeu de données dans Postgres et dans BigQuery.- Les blocs
qualityrattachent des attentes, soit à une colonne, soit à la table dans son ensemble.
L'anatomie d'une règle de qualité
Quatre champs font tout le travail :
| Champ | Ce qu'il signifie |
|---|---|
rule | Le contrôle à exécuter — nullCount, duplicateCount, validValues, between, regex, freshness, rowCount, referentialIntegrity, customSql |
dimension | La dimension de qualité à laquelle il appartient — completeness, uniqueness, conformity, accuracy, timeliness, consistency |
severity | error fait échouer l'exécution ; warning consigne la violation et poursuit |
mustBe | Le seuil, exprimé dans une petite grammaire lisible |
mustBe est ce qui rend les contrats agréables à lire. Ce n'est pas un langage d'expressions booléennes ; c'est une notation abrégée propre à chaque règle :
- Les règles de comptage prennent un comparateur :
"0","<= 5","> 0". Un nombre nu signifie « exactement ». betweenprend des bornes :"[0, 100000]".validValuesprend une liste :"['pending', 'paid']".regexprend un motif entre guillemets :"'^ORD-[0-9]{6}#39;".freshnessprend un âge maximal :"<= 24h","<= 2d".referentialIntegrityprend une cible :"customers.id".
Quelqu'un qui n'a jamais utilisé l'outil peut lire mustBe: "<= 24h" sur une règle freshness et savoir exactement ce qui va se passer. C'est tout l'objectif.
Les dimensions ne sont pas décoratives
Le champ dimension ressemble à de la taxonomie gratuite jusqu'au jour où vous avez une centaine de règles. Il devient alors le seul moyen de répondre aux questions que l'on pose vraiment : *sommes-nous couverts sur l'actualité pour nos jeux de données critiques, ou seulement sur la complétude ?* Des règles regroupées par dimension deviennent une matrice de couverture, et les trous de cette matrice sont généralement plus instructifs que n'importe quel contrôle en échec pris isolément.
Les six dimensions d'usage courant — complétude, unicité, conformité, exactitude, actualité, cohérence — sont suffisamment conventionnelles pour qu'un rapport de couverture signifie la même chose d'une équipe à l'autre.
Pourquoi un standard ouvert vaut l'effort
La portabilité est l'argument évident. Le même contrat décrit le même jeu de données logique, qu'il atterrisse dans PostgreSQL, BigQuery ou SQL Server. Le moteur d'exécution compile nullCount vers le SQL de chaque base. Une migration d'entrepôt cesse d'être une migration de règles.
La relecture est l'argument sous-estimé. Comme le contrat est un fichier, un changement de seuil devient un diff dans une pull request, avec un auteur et une raison. La propriété la plus précieuse d'un contrat de données n'est pas qu'une machine puisse l'exécuter — c'est qu'un humain puisse le contester avant sa fusion.
L'indépendance est l'argument stratégique. Des règles écrites dans un standard ouvert ne sont pas un actif de celui qui les exécute. Si vous remplacez l'outil de validation, les contrats vous suivent. Cela change la position de négociation, et cela change ce que vous êtes prêt à investir dans l'écriture des règles en premier lieu.
L'interopérabilité avec les catalogues. Comme ODCS porte aussi la propriété, les descriptions et les niveaux de service, le même document alimente un catalogue, un outil de traçabilité (lineage) et un moteur de validation, sans que trois sources de vérité distinctes ne divergent.
L'import et l'export, en pratique
Un standard ne vaut que par la facilité avec laquelle on y entre et on en sort. Deux règles empiriques.
L'import doit venir à vous. Pointez un outil vers une table existante : il devrait lire information_schema, en déduire les colonnes et les types, proposer un contrat de référence à partir de ce qu'il y trouve — les colonnes obligatoires deviennent des règles nullCount, les clés primaires des règles duplicateCount, les horodatages des candidats freshness — puis vous laisser éditer à partir de là. Partir d'un brouillon généré de trente règles et en supprimer dix est une expérience très différente de partir d'un fichier vide.
L'export doit être, octet pour octet, ce que vous éditez. C'est là que la plupart des outils échouent discrètement. Si le YAML n'est que le rendu d'une ligne de base de données, chaque aller-retour par l'interface reformate le fichier, réordonne les clés et supprime vos commentaires — et le diff de votre pull request devient du bruit illisible. Le contrat doit *être* le format de stockage, pas une projection de celui-ci.
Catalyst prend la seconde approche au pied de la lettre. Le YAML fait foi ; l'éditeur visuel de règles modifie le document en place, en préservant les commentaires et l'ordre des clés, de sorte qu'une règle ajoutée dans l'interface produit un diff d'une ligne. L'export est un téléchargement de fichier, l'import accepte tout document v3 valide, et rien n'est stocké dans une forme dont vous ne pourriez pas le ressortir.
Versionner un contrat
Utilisez le versionnage sémantique sur info.version, et prenez-le au sérieux :
- Patch — un seuil assoupli ou resserré, une description améliorée. Les consommateurs n'ont pas besoin de le savoir.
- Mineure — une nouvelle colonne, une nouvelle règle. Additif ; les consommateurs existants continuent de fonctionner.
- Majeure — une colonne supprimée ou renommée, un type modifié, une règle qui rejette désormais des données jusque-là acceptées. Cassant ; les consommateurs doivent être prévenus.
La discipline paie au moment où quelqu'un demande s'il peut supprimer une colonne sans risque. Avec des contrats versionnés et un diff, c'est une conversation de cinq minutes au lieu d'une semaine de grep.
La place des contrats à côté des tests dbt
Ils ne sont pas concurrents, et il vaut la peine d'être précis sur la différence.
Les tests dbt s'exécutent à l'intérieur d'un build dbt et couvrent les modèles dont dbt est propriétaire. Ils excellent exactement à cela et, si toutes les tables qui vous importent sont des modèles dbt, ils suffiront peut-être.
Un contrat de données se place un cran au-dessus. Il décrit la garantie du jeu de données indépendamment de ce qui l'a produit — dbt, Airflow, un notebook Spark, l'outil de réplication d'un éditeur, un chargeur écrit à la main — et indépendamment de qui exécute le contrôle. C'est l'interface entre un producteur et un consommateur, versionnée comme un artefact de premier rang.
En pratique, les équipes qui utilisent les deux placent les assertions rapides et peu coûteuses dans les tests dbt, où elles font échouer le build, et les promesses durables dans le contrat, où elles sont relues, versionnées et surveillées selon une planification, quel que soit le pipeline qui a écrit la table aujourd'hui.
Questions fréquentes
Que signifie ODCS ?
Open Data Contract Standard. C'est une spécification ouverte permettant de décrire le schéma, la propriété, les niveaux de service et les attentes de qualité des données d'un jeu de données dans un unique document YAML versionné, développée au sein du projet Bitol, sous l'égide AI & Data de la Linux Foundation.
ODCS et un contrat de données, est-ce la même chose ?
« Contrat de données » est le concept — une promesse convenue et versionnée entre un producteur de données et ses consommateurs. ODCS est un format ouvert et concret permettant de consigner cette promesse. Vous pouvez avoir des contrats de données sans ODCS, dans un format maison ; c'est l'usage d'un standard ouvert qui les rend portables d'un outil à l'autre.
Quelle est la différence entre ODCS et les tests dbt ?
Les tests dbt sont des assertions internes à un projet dbt, limitées aux modèles que dbt construit, et ils s'exécutent dans le cadre d'un build dbt. Un contrat ODCS décrit les garanties du jeu de données indépendamment de l'outil qui l'a produit ou qui le contrôle, il est versionné comme un artefact à part entière, et il peut être appliqué par n'importe quel moteur d'exécution compatible. Beaucoup d'équipes utilisent les deux.
Quelles règles de qualité des données ODCS prend-il en charge ?
Le bloc quality de la spécification est assez ouvert pour porter n'importe quelle règle qu'un moteur d'exécution comprend. En pratique, l'ensemble courant couvre la complétude (nullCount), l'unicité (duplicateCount), les valeurs autorisées (validValues), les plages numériques (between), la correspondance de motif (regex), la fraîcheur (freshness), les nombres de lignes (rowCount), l'intégrité référentielle, et une porte de sortie pour du SQL personnalisé. Chacune porte une dimension et une sévérité, de sorte que les résultats se consolident dans une vue de couverture.
Puis-je importer un contrat ODCS existant dans Catalyst ?
Oui. Catalyst lit tout document ODCS v3 valide, le valide au regard des colonnes importées du jeu de données — une règle référençant une colonne inexistante est donc détectée à l'enregistrement, avec un numéro de ligne — et stocke le YAML lui-même comme source de vérité. L'export vous restitue le même fichier, commentaires et ordre préservés.