Hva er en datakontrakt?
En datakontrakt er en avtale mellom produsent og konsument av data. Her er hva den inneholder, og hvordan den skiller seg fra katalog og dokumentasjon.
De fleste som har jobbet med data en stund, har opplevd det: en rapport som virket i går, viser tomme felt i dag. Ingen har gjort noe galt med vilje. Et system lenger opp i kjeden har endret seg, og endringen nådde frem til rapporten før den nådde frem til menneskene som var avhengige av den.
En datakontrakt er et forsøk på å gjøre slike avhengigheter synlige og forpliktende. Denne artikkelen forklarer hva en datakontrakt er, hva den bør inneholde, og hvordan den skiller seg fra verktøy og dokumenter du kanskje allerede har.
En avtale mellom produsent og konsument
På den ene siden står produsenten, teamet eller systemet som lager og vedlikeholder dataene, for eksempel teamet bak et ordresystem. På den andre siden står konsumentene, som leser dataene videre: analytikere som bygger rapporter, et dataplattformteam som laster dataene inn i et lager, eller et annet system som henter dem gjennom et grensesnitt.
Avtalen beskriver hva produsenten lover å levere, og dermed hva konsumentene kan bygge på. Det gjelder ikke bare hvilke kolonner som finnes, men også hva de betyr, hvem som eier dem, hvilken kvalitet de skal ha, og hvor ofte de oppdateres.
Det viktige ordet er avtale. En kontrakt er ikke en beskrivelse av hvordan dataene tilfeldigvis ser ut i dag, men en forpliktelse om hvordan de skal se ut. Endrer produsenten noe som bryter med kontrakten, er det en endring som må varsles og avtales, ikke noe konsumentene skal oppdage selv.
En datakontrakt skrives vanligvis i et maskinlesbart format, typisk YAML, og lagres sammen med koden i et versjonskontrollsystem som Git. Da kan endringer i kontrakten gjennomgås på samme måte som endringer i kode, og maskiner kan sjekke at dataene faktisk oppfyller den.
Hvorfor datakontrakter trengs
Tenk deg en nettbutikk med tre sentrale datasett: kunde, ordre og produkt. Ordresystemet er eid av et utviklerteam. Økonomiavdelingen har en månedlig omsetningsrapport som henter data fra ordre og slår dem sammen med produkt for å vise salg per produktkategori.
En dag rydder utviklerteamet i ordretabellen. Kolonnen belop får det mer presise navnet belop_eks_mva, og produkt_id endres fra et heltall til en tekststreng fordi et nytt varelager bruker alfanumeriske varenumre. For utviklerteamet er dette fornuftige forbedringer. Applikasjonen deres fungerer som før.
For økonomiavdelingen ser det annerledes ut. Rapporten finner ikke lenger kolonnen belop, og sammenslåingen mot produkt gir ingen treff, fordi produkt_id nå har en annen type på hver side. I beste fall feiler rapporten med en tydelig feilmelding. I verste fall viser den tall som ser riktige ut, men er feil, og noen tar beslutninger på grunnlag av dem.
Eksempelet viser to problemer som går igjen:
- Endringer oppstrøms brekker ting nedstrøms. Produsenten vet ikke hvem som bruker dataene, eller hvordan. Konsumentene får ikke vite om endringer før noe har gått i stykker.
- Eierskapet er uklart. Når rapporten viser feil tall, er det ikke åpenbart hvem som skal rette det. Er det utviklerteamet som endret tabellen, dataplattformteamet som laster den, eller analytikeren som skrev spørringen?
En datakontrakt løser ikke disse problemene av seg selv, men den gir dem en fast plass. Kontrakten sier at belop er en del av det produsenten har lovet å levere. Å gi kolonnen nytt navn blir dermed en kontraktsendring som må gjennom en avtalt prosess, med varsel til konsumentene og gjerne en overgangsperiode der begge kolonnene finnes. Og kontrakten sier hvem som eier datasettet, slik at det er klart hvem som skal kontaktes når noe er galt.
Hva en datakontrakt inneholder
Innholdet varierer mellom organisasjoner og standarder, men de fleste kontrakter dekker de samme fem områdene.
Skjema
Skjemaet beskriver strukturen: hvilke tabeller eller objekter datasettet består av, hvilke kolonner de har, og hvilken datatype hver kolonne har. Her står det også om en kolonne kan være tom, om den er en primærnøkkel, og hvordan tabellene henger sammen. For ordretabellen i eksempelet ville skjemaet slå fast at produkt_id er et heltall og en fremmednøkkel mot produkt.
Skjemaet er den delen av kontrakten som er lettest å kontrollere maskinelt, og den som oftest brytes ved uhell.
Betydning
Et kolonnenavn sier sjelden nok. Er belop med eller uten merverdiavgift? Er det beløpet kunden betalte, eller listeprisen før rabatt? Er en ordre med status levert levert til kunden eller bare sendt fra lageret?
Kontrakten bør derfor ha en beskrivelse av hver tabell og hver kolonne, skrevet slik at noen utenfor produsentteamet forstår den. Mange organisasjoner knytter i tillegg kolonnene til definerte forretningsbegreper, slik at «omsetning» betyr det samme i ordredataene som i økonomisystemet. Det er her mange misforståelser mellom fagmiljø og teknologi oppstår, og det er her en kontrakt gjør mest nytte utover det rent tekniske.
Eier
Kontrakten angir hvem som er ansvarlig for datasettet: et team, en rolle eller en navngitt person, og hvordan de kan nås. Eierskap betyr at noen har ansvar for at dataene oppfyller kontrakten, at endringer varsles, og at spørsmål blir besvart. Uten en eier er en kontrakt bare en beskrivelse.
Kvalitetsregler
Kvalitetsregler beskriver hva som skal være sant om dataene, utover at de har riktig form. Eksempler er at ordre_id skal være unik, at belop_eks_mva aldri skal være negativ, at hver ordre skal peke på en kunde som finnes, eller at andelen tomme e-postadresser i kunde skal ligge under en avtalt grense.
Reglene bør være så konkrete at de kan kjøres automatisk mot dataene. Da kan brudd oppdages når dataene produseres, i stedet for når noen leser en rapport.
Tjenestenivå
Tjenestenivået beskriver forventninger til leveransen. De vanligste er:
- Ferskhet: hvor gamle dataene kan være, for eksempel at gårsdagens ordrer skal være tilgjengelige innen kl. 06 neste morgen.
- Tilgjengelighet: hvor stor del av tiden datasettet skal kunne leses.
- Oppdateringsfrekvens: om dataene lastes løpende, hver time eller én gang i døgnet.
- Oppbevaring: hvor lenge historiske data tas vare på.
Mange kontrakter har også informasjon om hvor dataene ligger, hvem som har tilgang, og hvilken versjon av kontrakten som gjelder.
Slik kan en enkel kontrakt for ordre se ut i ODCS, standarden som er omtalt lenger ned:
apiVersion: v3.2.0
kind: DataContract
id: ordre
name: Ordre
version: 1.0.0
status: active
team:
name: Ordresystem
schema:
- name: ordre
properties:
- name: ordre_id
logicalType: string
required: true
description: Unik id for ordren
quality:
- metric: duplicateValues
mustBe: 0
- name: kunde_id
logicalType: string
required: true
description: Kunden som la inn ordren
- name: belop_eks_mva
logicalType: number
required: true
description: Beløp uten merverdiavgift
Hvordan en datakontrakt skiller seg fra en datakatalog
En datakatalog er en oversikt over hvilke datasett som finnes i en organisasjon. Den hjelper folk med å finne data, og viser ofte skjema, beskrivelser, eiere og lineage, altså hvor dataene kommer fra og hvor de går.
Ved første øyekast overlapper dette mye med en datakontrakt. Forskjellen ligger i retning og forpliktelse:
- En katalog beskriver det som er. Den henter som regel informasjon fra systemene og viser hvordan dataene ser ut nå. Endrer noen en kolonne, oppdateres katalogen.
- En kontrakt beskriver det som er lovet. Den skrives før eller ved siden av dataene og er en forpliktelse fra produsenten. Endrer noen en kolonne i strid med kontrakten, er det et brudd som skal oppdages og håndteres.
De to utfyller hverandre. En katalog kan gjerne vise kontraktene, slik at konsumentene ser både hva som finnes og hva de kan stole på. Men en katalog alene hindrer ikke at ordretabellen endres uten varsel.
Hvordan en datakontrakt skiller seg fra dokumentasjon
Mange team har allerede dokumentasjon av datasettene sine, i en wiki, et regneark eller en README-fil. Det er nyttig, men det er ikke en kontrakt.
Den første forskjellen er at dokumentasjon er skrevet for mennesker, mens en kontrakt også er skrevet for maskiner. Fordi kontrakten har en fast struktur, kan verktøy lese den, sammenligne den med de faktiske dataene og stoppe en endring som bryter den. En wikiside kan ikke stoppe noe.
Den andre forskjellen er at dokumentasjon lett blir utdatert. Den skrives én gang og oppdateres når noen husker det. En kontrakt som ligger i versjonskontroll sammen med koden, og som kontrolleres automatisk, blir utdatert på en synlig måte: avviket gir en feil, ikke bare en stille forskjell mellom tekst og virkelighet.
Den tredje forskjellen er forpliktelsen. Dokumentasjon forklarer, mens en kontrakt lover. Produsenten tar på seg et ansvar for å holde det kontrakten sier, og konsumentene får noe konkret å bygge på.
Åpne standarder for datakontrakter
Du kan skrive en datakontrakt i et format du lager selv, men det finnes åpne standarder som gjør kontraktene lettere å dele mellom team og verktøy. En av de mest brukte er Open Data Contract Standard (ODCS), som forvaltes av Bitol-prosjektet under Linux Foundation AI & Data. En ODCS-kontrakt er én YAML-fil med faste seksjoner for blant annet skjema, kvalitet, tjenestenivå og team. Gjeldende versjon er v3.2.0.
Fordelen med en standard er at du ikke trenger å finne opp strukturen selv, og at verktøy for kontroll, katalog og kodegenerering kan lese de samme filene. Hvordan ODCS er bygget opp, og hvordan feltene i standarden svarer til områdene over, er tema for en egen artikkel.
Hvor du kan begynne
En datakontrakt trenger ikke å dekke alt fra første dag. Et realistisk utgangspunkt er å velge ett datasett der en endring nylig har skapt problemer, og skrive ned skjemaet, en kort beskrivelse av hver kolonne og hvem som eier det. Når det er på plass, kan kvalitetsregler og tjenestenivå legges til etter hvert som produsent og konsumenter blir enige om dem.
Det viktigste er ikke formatet, men samtalen kontrakten tvinger frem: hva produsenten faktisk lover, og hva konsumentene faktisk trenger.
Kilder
- Bitol (datakontrakt som avtale mellom produsent og konsumenter, YAML, Linux Foundation AI & Data)
- Open Data Contract Standard v3.2.0, oversikt over seksjonene
- Open Data Contract Standard v3.2.0, grunnleggende felt (apiVersion, kind, id, version, status)
- Open Data Contract Standard på GitHub (gjeldende versjon)