Schema drift: wat er gebeurt als een bron een kolom hernoemt
Schema drift betekent dat de structuur van een bron verandert terwijl het datawarehouse ermee doorlaadt. Een kolom komt erbij, verdwijnt, krijgt een andere naam of een ander type. Elke pakketupdate levert minstens één van die vier op, en meestal voor tientallen tabellen tegelijk.
Na zo'n update leest Yres de structuur van de bron opnieuw. Het vergelijkt die met de tabellen in het datawarehouse en laat per tabel zien wat afwijkt. Het aanpassen van de tabellen is daarna één handeling.
Eén ding doet Yres bewust niet: een hernoeming herkennen. Waarom niet, en wat je dan wel doet, lees je hieronder aan de hand van de groothandel.
Gepubliceerd: · Laatst bijgewerkt: · Door Daniel Sanders, architect van Yres en oprichter van Plainwater
Vier soorten wijziging in één update
De leverancier van het boekhoudpakket van de groothandel rolt in de nacht van 1 op 2 oktober een nieuwe versie uit, met release notes van drie regels. Op de klantkaart komt het veld Betalingstermijn erbij. Het veld Plaats heet voortaan Vestigingsplaats. En het veld Korting, tot nu toe een tekst als '2,5%', wordt een getal met twee decimalen. Drie regels raken 30 tabellen, waaronder de klanttabel.
Daarin zitten alle vier de gevallen die schema drift kent:
- Een kolom erbij. De bron levert iets dat het datawarehouse nog niet kent, zoals Betalingstermijn.
- Een kolom weg. Het datawarehouse heeft een kolom die de bron niet meer levert. Bij de groothandel zit dat geval in de hernoeming verstopt.
- Een andere naam. Voor de bron is dat één wijziging. Voor het datawarehouse zijn het de twee vorige gevallen tegelijk: Plaats verdwijnt en Vestigingsplaats komt erbij.
- Een ander type. De kolom houdt dezelfde naam, maar de inhoud verandert, zoals bij Korting.
Voor een datawarehouse dat van elke rij elke versie bewaart, zoals ons artikel over historie bij honderden tabellen beschrijft, telt elk geval anders. Een kopie kun je weggooien en opnieuw maken. Een historietabel met twee jaar versies kun je dat niet.
Sanne, de data-engineer van de groothandel, ziet vrijdagochtend 2 oktober in het monitoringscherm dat de klanttabel die nacht niet is binnengekomen. De laadactie vroeg de bron nog om de kolom Plaats, die niet meer bestaat.
Hoe ziet Yres de wijziging?
Yres ziet een wijziging door de structuur van de bron opnieuw te lezen en die naast de echte tabellen te leggen. Dat heet metadata verversen. Het gebeurt per bron.
Sanne opent in het beheerscherm het boekhoudpakket en kiest metadata verversen. Daarna gebeurt dit:
- Lezen. Een pijplijn leest de catalogus van de bron, met schema's, tabellen, kolommen, types en lengtes.
- Klaarzetten. Die structuur landt eerst in een wachtruimte. De oude metadata blijft zolang staan.
- Omwisselen. Pas als de pijplijn klaar is en iets heeft opgeleverd, wisselt Yres de oude metadata van die bron in één transactie om voor de nieuwe.
Levert de bron niets op, bijvoorbeeld door een verbroken verbinding, dan blijft de oude metadata staan. Er komt dan een waarschuwing in het logboek. Een lege verversing kan zo nooit alle kolommen van een bron wissen. Wie meerdere bronnen heeft, kan ze in één keer laten verversen.
Daarna vergelijkt Yres. Aan de ene kant staat het gewenste model: de aangevinkte kolommen uit de metadata, vertaald naar de types van het datawarehouse. Aan de andere kant staan de echte tabellen in de database, de landingszone en de historietabel. Per kolom levert dat een van drie bevindingen op:
- De kolom staat in de metadata, maar niet in de tabel.
- De kolom staat in de tabel, maar niet meer in de metadata.
- De kolom staat in beide, met een ander type dan Yres er nu van zou maken.
De bevindingen worden per tabel vastgelegd. De tabel krijgt in het beheerscherm een waarschuwing dat de bron is afgeweken. Een vergelijkingsscherm toont de kolommen. De controlelijst van Yres meldt daarnaast elke aangevinkte kolom die niet meer in de metadata van de bron voorkomt. Gaat het om de kolom waarop de tabel zijn wijzigingen ophaalt, dan staat er een fout in plaats van een waarschuwing.
Hier zit het punt dat de rest van het verhaal bepaalt. De verversing is een vervanging: de oude metadata van de bron gaat eruit en de nieuwe komt erin. Een kolom in een catalogus heeft geen identiteit buiten zijn naam. Yres ziet dus niet dat Plaats is hernoemd naar Vestigingsplaats. Het ziet dat Plaats weg is en dat Vestigingsplaats nieuw is. De verversing schiet hier niet tekort, want de bron vertelt het zelf ook niet.
De types vertaalt Yres in drie lagen:
- Per kolom. Eerst kijkt Yres of een beheerder voor deze ene kolom een type heeft opgegeven.
- Per bron. Zo niet, dan kijkt het naar de vertaaltabel van deze bron.
- Per soort bron. Daarna volgt de productbrede vertaaltabel: wat een decimaal uit SQL Server wordt, wat een datum uit Oracle wordt, wat een tekst uit een API wordt.
Past niets, dan wordt het een breed tekstveld, zodat er in elk geval niets verloren gaat. Het veld Korting komt zo binnen als een getal met de precisie die de bron opgeeft. Het beheerscherm toont per kolom het brontype naast het doeltype.
Wat gebeurt er per geval?
Per geval past Yres de tabellen anders aan, met de handeling tabellen bijwerken vanuit de metadata. Je kiest per keer welke acties zijn toegestaan: kolommen toevoegen, types wijzigen of kolommen verwijderen.
Bij databasebronnen start je die handeling zelf, per bron of per tabel. Bij bestands-, REST- en SharePoint-bronnen zit hij in de laadpijplijn zelf, met alleen de acties toevoegen en type wijzigen. De landingszone wordt altijd weggegooid en opnieuw gemaakt, want daar staat niets dat bewaard hoeft te blijven. De historietabel wordt ter plekke aangepast. Alleen als die leeg is en alle drie de acties zijn toegestaan, maakt Yres ook de historietabel opnieuw. Wie bij de database kan, draait de handeling eerst in de proefstand. Yres toont dan het volledige script zonder iets aan te raken.
Betalingstermijn is de kolom die erbij komt. Na het verversen kent Yres hem, maar hij wordt nog niet geladen. Een kolom doet pas mee als hij in de metadata staat én bij de tabel is aangevinkt. Sanne opent de klanttabel, vinkt de kolom aan en werkt de tabel bij. De historietabel krijgt de kolom erbij, leeg voor alle bestaande versies. Van Dalen B.V. heeft op 25 september dus geen betalingstermijn, want toen bestond het veld nog niet.
Vanaf de volgende laadactie wordt de kolom gevuld, met een gevolg. De motor herkent wijzigingen aan een vingerafdruk van de inhoud van een rij, zoals het artikel over historie beschrijft. Die vingerafdruk wordt berekend over de aangevinkte kolommen. Een nieuwe kolom met een waarde verandert hem dus. Bij het eerste laden na het bijwerken sluit Yres daarom van elke klant met een betalingstermijn de actuele versie af en voegt een nieuwe toe. Dat klopt, want de rij is veranderd. Wie dat niet wil, kan de kolom per tabel buiten de vingerafdruk houden.
Plaats is de kolom die verdwijnt. Na het verversen staat hij niet meer in de metadata. De motor vraagt de bron er dus niet meer om. Ook de landingszone wordt zonder de kolom opnieuw gemaakt. De historietabel houdt hem met alle oude waarden: Zwolle bij de versie van Bakkerij Ter Horst die tot 2 oktober gold, Tilburg bij De Jong Transport, Leeuwarden bij Wielinga Interieur. Nieuwe versies krijgen in die kolom niets. De kolom uit de historietabel verwijderen is een aparte, bewuste keuze met de actie verwijderen. Daarna zijn de oude waarden weg. Zolang je dat niet doet, blijft de controlelijst erop wijzen dat een aangevinkte kolom niet meer in de bron bestaat.
Vestigingsplaats is de hernoemde kolom, dus de twee vorige gevallen tegelijk. De oude kolom Plaats blijft staan met waarden tot 2 oktober. De nieuwe kolom Vestigingsplaats komt erbij met waarden vanaf 2 oktober. De bakkerij verhuisde op diezelfde dag naar Deventer. Die verhuizing staat daardoor onder de nieuwe naam, met Deventer in Vestigingsplaats en Zwolle in Plaats bij de afgesloten versie. De historie is intact, alleen verdeeld over twee kolommen. Ook de naam van een kolom telt mee in de vingerafdruk. Bij de eerste laadactie na het bijwerken krijgt daarom elke klant een nieuwe versie, ook de klanten die niet verhuisd zijn.
Korting is de kolom die van type verandert. De vergelijking ziet dat de historietabel een tekstkolom heeft, waar de metadata nu een getal van zou maken. Bij het bijwerken doet Yres in één transactie het volgende:
- Opzij zetten. De oude kolom gaat opzij.
- Nieuwe kolom. Er komt een nieuwe kolom met het nieuwe type.
- Overzetten. De waarden worden met een conversie gekopieerd.
- Opruimen. De oude kolom gaat weg en de indexen worden opnieuw opgebouwd.
Laat één waarde zich niet converteren, dan draait alles terug. De tabel staat dan zoals hij stond en de fout staat in het logboek. Bij de groothandel gaat dat mis, want '2,5%' is geen getal. Sanne kan dan voor deze kolom een eigen doeltype opgeven, zodat de historie tekst blijft. Of ze laat de oude waarden eerst schonen.
| Geval | Na het verversen | Na het bijwerken |
|---|---|---|
| Kolom erbij | Bekend in de metadata, maar pas geladen als je hem aanvinkt | Kolom in de historietabel, leeg voor bestaande versies en gevuld vanaf de volgende laadactie |
| Kolom weg | Afwijking op de tabel en een waarschuwing in de controlelijst | Landingszone zonder de kolom. De historietabel houdt hem met de oude waarden, tenzij je verwijderen toestaat |
| Kolom hernoemd | Twee afwijkingen: de oude kolom is weg, de nieuwe is onbekend | Oude kolom met waarden tot de wijziging, nieuwe kolom met waarden vanaf de wijziging |
| Type gewijzigd | Afwijking: het type verschilt van wat Yres er nu van zou maken | Waarden overgezet naar het nieuwe type, in één transactie |
| Conversie die mislukt | Zelfde afwijking als hierboven | Alles teruggedraaid. De tabel staat zoals hij stond en de fout staat in het logboek |
| Verversing die niets oplevert | Waarschuwing in het logboek, de oude metadata blijft staan | Niets, want er is geen afwijking vastgesteld |
Waarom wordt een hernoeming niet herkend?
Yres herkent een hernoeming niet, omdat de bron niet vertelt dat een kolom een andere naam heeft gekregen. Een catalogus beschrijft alleen de stand van nu.
Elke lezer met een datawarehouse vraagt het zich af: waarom hernoemt Yres de kolom niet gewoon mee, zodat de historie in één kolom doorloopt? De catalogus vermeldt niet wat een kolom vorige week heette. Na de verversing heeft Yres een lijst waar Plaats niet meer op staat en Vestigingsplaats wel. Meer weet het niet.
Yres zou kunnen raden. Een kolom verdwenen, een kolom erbij, hetzelfde type en dezelfde positie in de tabel: dat zal wel een hernoeming zijn. Meestal klopt dat, soms niet. De leverancier kan tegelijk een veld hebben geschrapt en een ander veld hebben toegevoegd dat toevallig hetzelfde type heeft. Een verkeerde gok plakt dan stilzwijgend twee jaar historie van het ene veld aan een ander veld. Dat draai je pas terug als iemand het opmerkt. Twee kolommen naast elkaar zijn zichtbaar, een verkeerd samengevoegde kolom niet. Daarom laat Yres de keuze bij jou en toont het beide wijzigingen apart.
De eenvoudigste weg is de twee kolommen laten staan. Dat gebeurt vanzelf zolang je verwijderen niet toestaat. In je eigen view op de klanttabel zet je de twee samen: de nieuwe waarde als die er is, anders de oude. Rapporten die op die view draaien, zien dan één kolom. Yres bouwt na het bijwerken zijn eigen uitgifteview op de tabel opnieuw op. Views en rapporten die je zelf hebt gebouwd met de oude naam, pas je zelf aan. Het monitoringscherm laat zien wanneer de tabel is bijgewerkt, zodat je weet vanaf welke datum de nieuwe kolom gevuld is.
Voor tabellen kent Yres wel een hernoeming. Verander je in de instellingen van een tabel de naam die hij in het datawarehouse krijgt, dan hernoemt Yres bij het eerstvolgende bijwerken de landingszone en de historietabel fysiek. Dat gebeurt in één transactie, waarbij de uitgedeelde volgnummers meeverhuizen. Bestaat de nieuwe naam al, dan weigert Yres en logt het dat. De laadhistorie in het monitoringscherm blijft aan de oude naam hangen. Bestanden die al in de data lake staan, blijven onder het oude pad. Dit is een beheerhandeling voor de doeltabel. Voor kolommen bestaat zo'n handeling niet.
Wanneer gebruik je het?
Verversen, bekijken en bijwerken gebruik je bij elke structuurwijziging in een bron die al geladen wordt. Drie gevallen komen in de praktijk steeds terug.
Een pakketupdate die tientallen tabellen raakt. Zo ging het bij de groothandel. Je ververst één keer per bron en bekijkt per tabel wat afwijkt. Daarna vink je de nieuwe kolommen aan die je wilt hebben en werk je bij. Bij 30 tabellen is dat 30 keer kijken. Met het kopieerpatroon van Azure Data Factory uit het artikel over metadata-driven Copy Data bouw je 30 tabellen met de hand om.
Een bron die een tekstveld verbreedt. Het personeelssysteem maakt het veld Functietitel langer, van 50 naar 100 tekens. Na het verversen ziet de vergelijking een typeverschil. Bijwerken met type wijzigen zet de kolom om. Een verbreding converteert altijd, dus dit is het veiligste geval.
Een kolom die verdwijnt terwijl rapporten hem nog gebruiken. Het planningspakket schrapt het veld Routecode. De historietabel houdt de kolom met alle oude routecodes. Nieuwe versies hebben er niets in. De rapporten over vorig jaar blijven daardoor kloppen. Verwijderen sta je pas toe als niemand de oude waarden nog nodig heeft.
Het werkt voor elke bron die al geladen wordt, met verversen per bron en bijwerken per bron of per tabel. Bij databasebronnen start je het bijwerken zelf, eventueel eerst in de proefstand. Bij bestands-, REST- en SharePoint-bronnen zit het in de laadpijplijn en verwijdert het nooit iets.
De grenzen liggen bij het verleden en bij je eigen werk. Een nieuwe kolom blijft leeg voor alle versies van vóór het bijwerken, want Yres haalt het verleden van dat veld niet alsnog op. De eerste laadactie na een nieuwe of hernoemde kolom geeft elke geraakte rij een nieuwe versie. Views en rapporten die een oude kolomnaam gebruiken, pas je zelf aan.
Veelgestelde vragen
Past Yres mijn tabellen automatisch aan als de bron verandert?
Niet stilzwijgend. Bij databasebronnen start jij het bijwerken en kies je welke acties mogen. Bij bestands-, REST- en SharePoint-bronnen gebeuren toevoegen en type wijzigen tijdens het laden. Verwijderen gebeurt daar nooit vanzelf.
Waarom hernoemt Yres de kolom niet gewoon mee, zodat de historie doorloopt?
Omdat een verkeerde gok niet te zien is. Twee kolommen naast elkaar vallen op. Twee velden die ten onrechte zijn samengevoegd, zien eruit als één nette kolom. Wil je toch één kolom, dan zet je de twee samen in je eigen view.
Verlies ik historie als een kolom uit de bron verdwijnt?
Nee, zolang je bij het bijwerken verwijderen niet toestaat. Alleen de landingszone verliest de kolom, maar die bewaart toch niets. Sta je verwijderen wel toe, dan zijn de oude waarden echt weg.
Wat gebeurt er als een typewijziging niet te converteren is?
Dan verandert er niets aan de tabel en staat de fout in het logboek. Daarna kies je een eigen doeltype voor die kolom of laat je de afwijkende waarden schonen. Dan werk je de tabel opnieuw bij.
Moet ik na een pakketupdate alle bronnen verversen?
Alleen de bron die een update kreeg. Een verversing vervangt de metadata van één bron. Kregen meerdere bronnen tegelijk een update, dan kun je ze ook in één keer laten verversen.
Praat met een data-architect
In 30 minuten kijkt een data-architect met je mee naar je huidige dataomgeving en waar het nu wringt.
Plan een gesprek →
