·
7 Min Lesezeit
·
Geschrieben von Tomáš Mikeš
ETL mit 50+ Quellen: Schema-Drift und Quality-Gates automatisieren
Magistra-DWH integriert Daten aus 50+ Quellen — Apotheken, E-Shop, HR, externe APIs. Schema ändert sich ohne Warnung, Datenqualität schwankt. Contract-Testing, Quality-Gates und Observability-Pipeline als Code.
„Wir haben 50 Source-Systeme.“ Wenn ich das beim Kickoff höre, weiß ich, dass der größte Pain-Point nicht die Transformationen sind. Es ist Schema-Drift — Source-Systeme ändern sich ohne Warnung, und Ihre ETL-Pipelines fallen um 3 Uhr morgens, weil jemand im SAP entschied, vormittags eine Spalte hinzuzufügen.
Für Magistra (50+ Quellen: Apotheken, E-Shop, HR-System, DNS-Server, externe CSV-Feeds, SOAP-APIs…) mussten wir das Pipeline-first lösen. Was funktioniert:
Problem 1: Source-Team fügt Spalte hinzu, Sie wissen nichts
Das Apotheken-System in 200 Filialen fügt eine loyalty_tier-Spalte an der Customer-Tabelle an. Source-Team sagt es DWH-Team nicht — warum sollten sie, ihr System funktioniert. Ihr ETL SELECT * liefert plötzlich eine Spalte mehr, Schema-Drift bricht alles Downstream.
Lösung: explizite Schema-Deklaration im ETL-Code, kein SELECT *:
-- Quelle: pharmacies_customer SELECT customer_id, -- INT NOT NULL full_name, -- VARCHAR(200) email, -- VARCHAR(200) NULL registered_at -- TIMESTAMP FROM pharmacies_customer WHERE updated_at > :last_load_time
Fügt Source loyalty_tier hinzu, nimmt unser SELECT es nicht, aber die Pipeline läuft weiter. Source-Team hat 30 Tage, die Änderung zu melden. Sonst verpassen wir das neue Feld, nicht den ganzen Load.
Ein Schema-Validator läuft 1× täglich gegen das Source-System. Er vergleicht das aktuelle Schema mit dem erwarteten (als YAML im Repo gespeichert). Diff = Alert. „In pharmacies_customer gibt's neue Spalte loyalty_tier. Ins DWH aufnehmen oder ignorieren?“ Menschliche Wahl, nicht automatisch.
Problem 2: Data-Quality-Gates vor dem Load
Eine neue Version des E-Shop-Exports hat 30 % Zeilen mit leerem customer_email. In vorherigen Exports waren es 2 %. Auf der Source-Seite ist was passiert. Ohne Kontrolle zu laden = DWH verseuchen.
Quality-Gates an jeder Quelle:
- Row-Count: liegt der aktuelle Load in vernünftigem Bereich gegenüber dem letzten Monat? (±30 %)
- Null-Rate pro kritischer Spalte: customer_id darf > 0 Nulls haben, E-Mail < 5 %
- Referentielle Integrität: jedes order.customer_id muss in der customer-Tabelle existieren
- Business-Invarianten: Summe Pricing-Spalten = Total, Datenkonsistenz zwischen Tabellen
Gate-Fail = Load stoppt, Alert zu Menschen, im DWH ändert sich nichts. Verhindert, dass der CFO auf ein Dashboard schaut und 30 % Kunden ohne E-Mail sieht, weil auf der Source-Seite etwas kaputt ging und wir es bereitwillig durchgereicht haben.
Problem 3: Observability über die ganze Pipeline
Daten durchlaufen 5 Schichten: Source-Pull → Staging → Raw → Enriched → Presentation. Erscheinen in Presentation komische Zahlen, wo ist das Problem?
Metrik pro Stage:
- Rows in, Rows out, Rows rejected (Quality-Gate)
- Stage-Duration (p50, p99)
- Error-Count, Error-Types
- Data-Freshness (neuester Timestamp pro Tabelle)
Alles in zentrale Observability (in Magistra nutzen wir Application Insights + Custom-Dashboards in Power BI — ja, Monitoring der Data-Plattform in ihr selbst).
Problem 4: Idempotente Re-Runs
Nachts fällt die ETL-Pipeline mittendrin wegen Netzwerk-Hiccup an der Source-DB. Was jetzt? Zwei Extreme:
- Restart from scratch — Target-Daten löschen und neu laden. Bei großen Tabellen (Millionen Zeilen) Stunden Arbeit.
- Resume from Checkpoint — wenn Sie wissen, wo er aufhörte, weitermachen. Schnell, aber Sie müssen Idempotenz garantieren.
Lösung: Upserts mit deterministischen Keys. Jeder ETL-Write ist MERGE INTO target USING source ON target.key = source.key WHEN MATCHED UPDATE... WHEN NOT MATCHED INSERT.... Pipeline re-runnen und bereits geladene Zeilen werden identisch überschrieben (No-op); neue kommen dazu. Deterministisch, sicher.
Problem 5: Contract-Testing mit Source-Teams
Bester Fall: Source-Team sagt vorher „Schema ändert sich, passt ETL an“. Mittlerer Fall: Sie entdecken es aus dem Schema-Validator. Schlechtester: Sie merken es 3 Tage nach Change durch Quality-Gate-Alert.
Contract-Testing formalisiert Erwartungen:
- Eine YAML-Datei zwischen Source-Team und DWH-Team definiert erwartetes Schema + Invarianten (auf Constraint-Ebene, nicht nur Types)
- Source-Team-CI führt diesen Contract-Test gegen Testing-Environment vor Deploy aus — würde die Änderung den DWH-Contract brechen, wird Deploy blockiert
- Besser als SNS-Alert: Source-Team sieht im CI, dass Downstream brechen würde, und spricht mit dem DWH-Team davor, nicht danach
Das funktioniert nicht für 3rd-Party-Sources (externe APIs, CSV-Feeds). Dort bleibt Schema-Validator + Quality-Gates. Aber für interne Sources ist Contract-Testing ein Game-Changer.
Magistra-Implementierung
Nach 6 Betriebsmonaten:
- 52 Source-Systeme, 140+ ETL-Pipelines
- 18 Schema-Drift-Alerts über 6 Monate — 15 nicht-blockierend, 3 erforderten ETL-Anpassungen
- Quality-Gate-Fails ~2× pro Woche — meist transiente Issues (Source-System-Migrationen)
- Mean-Time-to-Detection für Data-Korruption: < 2 Stunden (gegen ~3 Tage vorher)
- Contract-Testing mit 4 internen Source-Teams (restliche 8 sind Legacy, migrieren schrittweise)
Zum Mitnehmen
ETL mit vielen Quellen geht nicht darum, Transformationen zu beherrschen. Es geht darum, zu wissen, wann etwas kaputt ist. Ohne das sammelt Ihr DWH langsam Bad-Data, und eines Tages merkt der CFO, dass die Zahlen seit 3 Monaten falsch sind. Rückwirkend korrigieren = Horror.
Drei Säulen:
- Explizites Schema im ETL-Code, kein SELECT *
- Quality-Gates am Eingang jeder Quelle
- Observability aus jeder Stage, nicht nur Endergebnis
Plus Contract-Testing mit internen Source-Teams, falls politisch möglich. All das ist kein Luxus — für 50+ Source-Systeme ist es das Minimum.
Arbeiten Sie an etwas Ähnlichem?
Vereinbaren Sie ein 30-minütiges technisches Gespräch. Kein Vertriebsprozess — direktes architektonisches Feedback.