De meeste genealogische hulpmiddelen worden gebruikt voor archeologisch onderzoek.
De standaardaanpak voor kolomherkomst werkt als volgt: je pipeline draait, querylogs komen ergens terecht, een tool voor kolomherkomst analyseert die logs en er wordt een grafiek gemaakt die laat zien welke kolommen welke downstream-tabellen hebben gevoed. Tools zoals DataHub, Atlan en OpenLineage volgen allemaal een variant van dit patroon. De grafiek is nuttig. Hij beantwoordt vragen over de dataflow. Maar hij beantwoordt die vragen pas nadat de schade al is aangericht.
Het fundamentele probleem is timing. Een achteraf opgestelde grafiek voor kolomherkomst vertelt je dat orders.customer_id is doorgegeven aan revenue_by_segment.segment_key — verleden tijd. Hij kan je niet vertellen dat het hernoemen van customer_id naar cust_id in de bron drie downstream-modellen zal laten crashen voordat je die wijziging naar productie doorvoert. Je ontdekt dat pas wanneer de pipeline om 2 uur 's nachts vastloopt, of erger nog, wanneer hij wel slaagt maar een join uitvoert op een NULL-kolom en niemand het dagenlang merkt.
Rocky, een open-source Rust-project dat deze week op Hacker News verscheen (202 sterren, Apache 2.0-licentie), kiest voor een andere aanpak. Het compileert de kolomherkomst uit de SQL-grafiek tijdens het compileren, op dezelfde manier als een Rust-compiler het eigenaarschap van typen traceert via functieaanroepen. De herkomst wordt niet gereconstrueerd uit logs. Deze wordt berekend op basis van de gedeclareerde transformaties voordat de uitvoering begint. Dit onderscheid klinkt academisch, totdat je bedenkt wat het voorkomt: query's die correct worden geparseerd, foutloos worden uitgevoerd, maar stilletjes onjuiste resultaten opleveren omdat de semantische relatie tussen kolommen stroomopwaarts is veranderd.
Rocky-afstamming -- kolom traceert voorouders vóór executie
Rocky's CLI biedt lineage als een volwaardige compileertijdbewerking. Door rocky lineage --column revenue_by_segment.total_revenue uit te voeren, wordt de afhankelijkheidsgrafiek achterwaarts doorlopen via joins, CTE's en windowfuncties, waarbij elke bronkolom die bijdraagt aan de uitvoer wordt geretourneerd. Dit gebeurt op basis van de gecompileerde modeldefinities, niet op basis van warehousemetadata of historische querylogboeken.
Het praktische verschil komt in drie scenario's naar voren. Ten eerste, blast-radius-analyse: voordat een kolom in een seed- of brontabel wordt hernoemd, voert je rocky lineage-diff HEAD~1 uit om precies te zien welke downstream-kolommen in het hele project worden beïnvloed. Ten tweede, contracthandhaving: Rocky's compiler genereert diagnostische code E010 wanneer een model verwijst naar een kolom die niet bestaat in de gedeclareerde invoer, en E013 wanneer een beveiligde kolom wordt verwijderd of het type ervan onveilig verandert. Beide worden geactiveerd tijdens rocky compile, niet tijdens rocky run. Ten derde, validatie van door AI gegenereerde modellen: Rocky kan modellen genereren op basis van natuurlijke taal, maar elke gegenereerde query doorloopt dezelfde compiler. Een onjuiste join op een niet-bestaande kolom veroorzaakt een E010-fout voordat de SQL je datawarehouse bereikt.
De architectuur die dit mogelijk maakt, is een Rust-workspace met 21 crates die Rocky's DSL (.rocky-bestanden) parseert, typen oplost en een volledige afhankelijkheidsgrafiek op kolomniveau opbouwt tijdens het compileren. Modellen worden gedefinieerd in een TOML-gebaseerde configuratie met expliciete type-annotaties, waardoor de compiler voldoende informatie heeft om de herkomst te traceren zonder iets uit te voeren. Opslag en rekenkracht blijven in je datawarehouse — Databricks (productie), Snowflake (beta), BigQuery (beta) of DuckDB voor lokaal testen.
Detectie van schemaafwijkingen zorgt ervoor dat het bestand wordt verwijderd en opnieuw wordt aangemaakt in plaats van stilletjes te worden beschadigd.
Schema-drift is een fout in de dataoverdracht die er niet uitziet als een echte fout. Een bronsysteem wijzigt een kolom van INTEGER naar VARCHAR. Je pipeline blijft gewoon draaien. Downstream-aggregaties beginnen stringrepresentaties op te tellen of, afhankelijk van het datawarehouse, stilletjes te casten met afkapping. De getallen in je Power BI rapport veranderen met zulke kleine hoeveelheden dat niemand er wekenlang naar kijkt.
Rocky pakt dit aan door bij elke run de bronschema's te vergelijken met de gecompileerde modelgrafiek. Wanneer het detecteert dat een kolomtype in de bron upstream is gewijzigd, probeert het geen soepele migratie uit te voeren. Het verwijdert de betreffende doeltabellen en maakt ze opnieuw aan. Dit is een agressieve aanpak, en dat is de bedoeling — het alternatief is het verspreiden van corrupte data door elk downstream-model dat de gewijzigde kolom gebruikt.
Het branchsysteem biedt een veiligheidsmechanisme om schemawijzigingen te testen voordat ze in productie worden genomen. rocky branch create experiment-1 maakt een logische kopie van de tabellen in de pipeline met behulp van schema-prefixisolatie (met native Delta SHALLOW CLONE en Snowflake zero-copy cloning op de roadmap). Je voert je pipeline uit op de branch, inspecteert de resultaten en promoot of verwijdert ze vervolgens. De branch werkt met een apart schema, waardoor de productietabellen tijdens experimenten onaangeraakt blijven.
Er is hier echter een belangrijk aandachtspunt: snapshot modellen op branches beginnen met lege tabellen en accumuleren gegevens van de eerste branch-run. Ze erven geen geschiedenis van de main-branch. Hugo Correia, de maker van Rocky, erkende deze beperking direct in de Hacker News-discussie. Voor teams die sterk afhankelijk zijn van langzaam veranderende dimensiepatronen, betekent dit dat branch-testen van snapshot modellen het productiegedrag niet zullen weerspiegelen totdat snapshots volledig worden ondersteund.
Compileertijdcontracten versus runtime-verrassingen
Het dbt-model heeft het idee populair gemaakt dat SQL-transformaties versiebeheerd en testbaar moeten zijn. Rocky breidt dit uit door datacontracten af te dwingen tijdens het compileren, in plaats van schendingen na uitvoering op te sporen. Het verschil is vergelijkbaar met het verschil tussen TypeScript en JavaScript: beide laten je dezelfde logica schrijven, maar de ene detecteert typefouten voordat je code wordt gepubliceerd.
De .rocky-modelbestanden van Rocky declareren expliciete typen voor invoer en uitvoer. De compiler valideert deze declaraties aan de hand van de daadwerkelijke datawarehouse-schema's tijdens rocky compile. Als een model order_date TIMESTAMP verwacht, maar de bron is afgeweken naar order_date DATE, signaleert de compiler de mismatch voordat rocky run SQL naar je datawarehouse stuurt. Anders Brownworth van dbt Labs reageerde op de Hacker News-thread: "gaaf project -- ik ben vooral enthousiast over de vertakkings- en budgetteringsopties die jullie hebben ingebouwd. Beide zijn dingen die ik graag in de dbt-standaard zou willen zien."
De functie voor kostentoewijzing versterkt deze filosofie van compileren tijdens de uitvoering. Rocky registreert het aantal gescande bytes en de uitvoeringsduur per model, met configureerbare budgetdrempels (max_usd, max_duration_ms) die CI-pipelines kunnen blokkeren. Een model dat na een schemawijziging plotseling tien keer zoveel data scant, wordt direct in de CI gedetecteerd en verschijnt niet drie weken later op je cloudrekening. De handhaving is nog niet volledig – drempels voor gescande bytes worden wel geregistreerd, maar kunnen nog niet als harde CI-blokkering worden ingesteld – maar alleen al de zichtbaarheid van de kosten per model verandert de manier waarop teams over schemawijzigingen nadenken.
SQL blijft de dominante datataal op elk ervaringsniveau in het Stack Overflow-onderzoek van 2024, gebruikt door 51% van alle respondenten en 54,1% van de professionele ontwikkelaars. Tools die de correctheid van SQL-pipelines vóór de uitvoering afdwingen, vullen een reële lacune op: SQL heeft geen ingebouwd typesysteem dat transformatiegrenzen overstijgt.
Replay reconstrueert de exacte invoergegevens die tot een resultaat hebben geleid.
Het debuggen van een datakwaliteitsprobleem drie dagen nadat het zich voordeed, betekent doorgaans het lezen van logs, het gissen naar de status van de brontabellen tijdens de uitvoering en hopen dat er tussendoor niets is getruncateerd en opnieuw geladen. Rocky's rocky replay -opdracht reconstrueert welke SQL-statements op welke inputs zijn uitgevoerd voor een specifieke historische uitvoering, waardoor je een reproduceerbaar overzicht krijgt van wat de pipeline daadwerkelijk heeft gedaan.
Dit is geen tijdreisquery op het datawarehouse. Het is metadata-replay: Rocky's ingebouwde state store registreert de exacte SQL, de watermark-posities voor incrementele modellen en de schema-signatures tijdens de uitvoering. Wanneer je een run opnieuw afspeelt, ziet je de precieze omstandigheden die de output hebben gegenereerd, zonder dat je beleid voor het bewaren van snapshots op datawarehouse-niveau hoeft te onderhouden.
Voor incrementele modellen lost dit een bijzonder lastig debugscenario op. Een model dat is geconfigureerd met strategy = "incremental" en een timestamp_column houdt zijn hoogste watermark bij in Rocky's state store. Vervolgruns verwerken alleen rijen waarvan de tijdstempel de opgeslagen watermark overschrijdt. Wanneer een incrementeel model onverwachte resultaten oplevert, toont rocky replay de exacte watermarkpositie en het invoervenster voor die run, in plaats van dat je deze moet reconstrueren aan de hand van de querygeschiedenis van het datawarehouse.
De combinatie van replay en compile-time lineage creëert een audit trail die in beide richtingen werkt: voorwaarts van bronkolommen naar downstream outputs via rocky lineage, en achterwaarts van de resultaten van een specifieke run naar de exacte inputs en transformaties die deze hebben geproduceerd via rocky replay. MetricSign vult dit aan door de operationele laag te monitoren: het detecteert wanneer geplande pipeline-runs mislukken, groepeert gerelateerde fouten over afhankelijke modellen en brengt de hoofdoorzaak in kaart die datawarehouse-fouten koppelt aan het specifieke model of de bron die de cascade heeft veroorzaakt.
Waar Rocky past en waar de hiaten nog bestaan.
Rocky is een controlelaag, geen datawarehouse. Het slaat zelf geen data op en voert geen query's uit. Je Databricks-, Snowflake- of BigQuery-cluster verzorgt de rekenkracht en opslag. Rocky beheert de grafiek: afhankelijkheden, typen, driftdetectie, lineage, kostentoewijzing en governancebeleid zoals kolommaskering via rocky compliance --env prod --fail-on exception.
De Rust-basis van het project biedt praktische voordelen voor CI-integratie. Een enkele statische binaire code betekent dat er geen Python-omgeving beheerd hoeft te worden en dat er geen conflicten zijn met afhankelijkheden van je bestaande dbt- of Airflow-installaties. De compilatiestap is snel genoeg om bij elke pull request te worden uitgevoerd, waardoor lineage-breuken en typefouten worden opgespoord voordat de codebeoordeling begint.
Er zijn echter wel beperkingen. Er is geen gehoste gebruikersinterface of beheerde scheduler – Rocky raadt Dagster aan voor orchestratie. De snapshot beperking op branches betekent dat teams met SCD Type 2-patronen wijzigingen in branches niet volledig kunnen valideren. De handhaving van het bytes-scan-budget is weliswaar in de logs te vinden, maar niet als een harde CI-gateway. Het project bevindt zich nog in een vroeg stadium (400 commits, 10 branches, bèta-connectoren voor Snowflake en BigQuery), en de DSL is specifiek voor Rocky in plaats van standaard SQL, wat migratiekosten met zich meebrengt voor bestaande dbt-projecten.
Maar het kerninzicht is terecht: kolomherkomst die tijdens het compileren wordt berekend op basis van de transformatiegrafiek, detecteert een klasse fouten die achteraf uitgevoerde tools structureel niet kunnen detecteren. De query die wordt geparseerd, uitgevoerd en onjuiste getallen produceert omdat een semantische relatie stroomopwaarts is gewijzigd – dat is de foutmodus die teams de meeste tijd en geloofwaardigheid kost. Het detecteren van deze fout vóór de uitvoering, met een diagnostische code en een duidelijk rapport over de impact, is de migratiekosten waard voor teams die al te vaak de dupe zijn geworden van stille schemawijzigingen.