Eigene OpenMetadata-Adapter: Vom Metadaten-Fixture zum betriebenen Connector
Mit ausführbaren Excel-Ordner- und QVD-Header-Beispielen, Python-Starter, Tests und OpenMetadata-Pilot.
Quellen- und Prüfstand: 15. Oktober 2026. Bezug: OpenMetadata-Dokumentation 2.0.x. Das offizielle Demo nennt als getestete Paketversion openmetadata-ingestion==2.0.0.0rc1. Daraus folgt keine Freigabe für jede spätere 2.0-Version. Den eigenen Server, Runner, SDK-Pin und Connector gemeinsam testen.
Wann ein eigener Adapter sinnvoll ist
Prüft zuerst den nativen Connector-Katalog. Für Qlik, Tableau, PostgreSQL, Snowflake oder Unity Catalog ist ein vorhandener Connector meist der bessere Start. Ein eigener Adapter lohnt sich beispielsweise für ein internes Fachsystem, eine proprietäre Metadaten-API oder fehlende Objekttypen. Eine zusätzliche Quell-API ist nicht automatisch ein neuer OpenMetadata-Entitätstyp: zuerst das fachlich passende Modell wählen.
Der Connector-Starter erzeugt ein kleines CustomDatabase-Gerüst. Es liest eine mitgelieferte JSON-Metadaten-Datei und liefert Service, Datenbank, Schema, Tabelle und Spalten. Das ist ein überprüfbarer Startpunkt für Tabellenmetadaten; Dashboards, Pipelines oder Messaging brauchen andere Request-Modelle. Geschäftsdaten lädt dieses Beispiel nicht.
1. Auftrag und Identitäten festlegen
Vor dem Programmieren fünf Antworten festhalten: Welche Objekte gehören zum Pilot? Wie identifiziert die Quelle sie stabil? Welche Metadaten darf der Runner lesen? Welches Team betreibt den Connector? Woran erkennt der Fachbereich den erfolgreichen Lauf?
Beispiel: Ein internes Auftragsportal liefert ein Verzeichnis von Tabellen und Spalten. Der Pilot umfasst pilot.sales.orders, keine Kundenzeilen. Die unveränderliche Quell-ID und der fachliche Name werden getrennt geführt. Produktion und Test erhalten verschiedene Services; ein Umbenennen darf nicht unbemerkt eine zweite Identität erzeugen.
2. Paket erzeugen und offline prüfen
Im Starter Python-Modul und dedizierten Pilot-Service festlegen. Die exakte installierte SDK-Paketversion mit python -m pip show openmetadata-ingestion ermitteln; der Python-Paketname kann eine andere Versionsschreibweise als der Server verwenden. Der Generator prüft einfache Namen und die 2.0-Versionsbasis, jedoch weder Paketverfügbarkeit noch vollständige Kompatibilität.
Das TAR-Paket entpacken. Es enthält source.py, normalize.py, eine Metadaten-Fixture, workflow.yaml, pyproject.toml, Tests und README. Im Paketordner ausführen:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements-files.txt
python -m unittest discover -s tests -v
python -m compileall -q company_catalog
Bei geändertem Modulnamen das Modul im compileall-Befehl entsprechend ersetzen. Diese Prüfungen brauchen weder SDK noch Server. Sie prüfen unter anderem doppelte Tabellen, unbekannte Datentypen und mehrdeutige Namen. Sie bestätigen noch keinen funktionierenden Ingestion-Lauf.
3. Den Source-Vertrag verstehen
OpenMetadata lädt eine Python-Klasse im Ingestion-Runner. Unser Gerüst setzt auf Source mit create, prepare, test_connection, _iter und close. create validiert den Workflow, prepare prüft die Fixture, _iter liefert typisierte Create-Requests über Either(right=...). Der Sink schreibt die Metadaten. Die Klasse ist im Workflow als company_catalog.source.FixtureSource eingetragen.
Die Reihenfolge ist Service → Datenbank → Schema → Tabelle. Ein späterer Lineage-Schritt braucht bereits gespeicherte Endpunkte. Für solche Abhängigkeiten den versionspassenden Barrier-Mechanismus oder einen getrennten Lauf verwenden. Nicht allein aus gleichen Namen eine Herkunft ableiten.
4. Die eigene Quell-API anbinden
Ersetzt das Lesen der Fixture durch einen kleinen Metadaten-Client. Behaltet die Normalisierung als getrennte Funktion, damit API-Änderungen keine unbemerkten Modelländerungen erzeugen. Für den ersten Ausbau diese Arbeitspakete einplanen:
| Arbeitspaket | Nachweis vor Freigabe |
|---|---|
| Authentifizierung | Technische Identität mit minimalem Scope; Rotation und abgelaufenes Token getestet |
| Seitenweise Abfrage | Erste, mittlere und letzte Seite; keine verlorenen oder doppelten Objekte |
| Fehlerverhalten | Timeouts, HTTP 429 und temporäre Ausfälle; begrenzte Retries und Backoff |
| Typmapping | Jede Quellspalte wird explizit einem unterstützten OpenMetadata-Typ zugeordnet |
| Namen | Stabile FQNs; für Punkte und Quotes SDK-konforme Escaping-Regeln ergänzen |
| Teilfehler | Fehler sichtbar als Run-Fehler oder bereinigtes Either(left=StackTraceError(...)) |
| Lebenszyklus | Umbenennen, verschwundene Objekte und Wiederanlauf bewusst behandeln |
Die Vorlage beendet einen ungültigen Fixture-Lauf mit Fehler. Sie hat noch keinen Netzwerk-Client, keine Wiederholungslogik, keine Löschlogik und kein Checkpointing. Ein fehlgeschlagener Scan darf niemals als erfolgreicher leerer Bestand gewertet werden. Sonst könnte eine spätere Löschlogik gültige Objekte entfernen.
5. Im richtigen Runner installieren
In einer isolierten Python-Umgebung das Paket installieren und den Import der Source-Klasse testen. Danach mit der exakten Zielversion Workflow- und Request-Modelle in CI validieren. Erst dann auf einem freigegebenen Testserver ausführen. Die Befehle und Umgebungsvariablen stehen im erzeugten README; metadata ingest -c workflow.yaml schreibt echte Metadaten in diesen Server.
Für UI-gesteuerte Ingestion muss das Paket im verwendeten Runner-Image installiert sein. Nur ein Paket auf dem Laptop oder dem OpenMetadata-Server reicht nicht. Basis-Image passend zum Server-Release wählen, Paket ohne Austausch der Image-Abhängigkeiten installieren und Fixture beziehungsweise Client-Konfiguration im Runner bereitstellen. Secrets aus dem Secret Manager beziehen, keine Tokens in Git oder Testdateien.
6. Abnahme und Betrieb
Zwei Läufe müssen dieselben Identitäten ergeben. Danach Ausschlüsse, fehlende Rechte, Secret-Rotation und einen simulierten Quellausfall testen. Ein Fachverantwortlicher bestätigt die fachliche Bedeutung einer Beispielspalte. Betriebsowner, Zeitplan, Alarmierung, Supportweg und Aufwand für SDK-Upgrades gehören ins Übergabeprotokoll.
Owner, Tags, Glossarbegriffe, Profiling und Lineage sind eigene Erweiterungen mit echten Referenzen und Freigaben. Der Einrichtungsplaner hält Prüfstatus und offene Punkte fest; der Mapping-Prüfer unterstützt den formalen Quellenabgleich.
7. Praxisbeispiel: einen Excel-Ordner katalogisieren
Der Connector-Starter enthält jetzt zwei ausführbare Datei-Beispiele, synthetische Demo-Eingaben und Tests. Im Paket unter examples/README.md stehen alle Befehle. Stand der Erweiterung: 23.10.2026, Python 3.10–3.12, Excel-Leser openpyxl==3.1.5 mit defusedxml==0.7.1. Der OpenMetadata-Teil bleibt auf die oben genannte 2.0.x-Vertragslinie begrenzt und braucht den exakten eigenen SDK-Pin.
Das Modell ist bewusst einfach: Pilot-Service → Datenbank local_files → Schema excel → eine Tabelle pro Arbeitsblatt → Spalten aus der Kopfzeile. Es ist eine eigene Tabellenprojektion, kein behaupteter nativer Excel-/Drive-Connector. Dateipfad, Blatt und ursprüngliche Feldnamen bleiben als beschreibende Metadaten erkennbar.
Nach dem Entpacken in einer isolierten Umgebung starten:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements-files.txt
python -m unittest discover -s tests -v
python -m company_catalog.make_demo ./demo-input
python -m company_catalog.file_scanner excel ./demo-input/excel --output ./fixtures/excel.json
Bei anderem Modulnamen company_catalog ersetzen. Das Demo erzeugt orders.xlsx mit einem sichtbaren Blatt Orders, zwei Textüberschriften und synthetischen Zeilen sowie einem versteckten Blatt. Versteckte Blätter sind standardmäßig ausgeschlossen. Für einen freigegebenen eigenen Ordner:
python -m company_catalog.file_scanner excel /freigegeben/excel --header-row 1 --exclude 'archive' --exclude '*/archive' --output ./fixtures/excel.json
Der Scan läuft rekursiv; Ausschlüsse beziehen sich auf relative Pfade mit /, beachten Groß-/Kleinschreibung und sind kein Gitignore-Format. --header-row 3 liest die dritte Zeile als Spaltennamen. --include-hidden nimmt versteckte Blätter bewusst hinzu. Unterstützt sind .xlsx und .xlsm; Makros und Formeln werden nicht ausgeführt. .xls, .xlsb, geschützte/verschlüsselte oder beschädigte Dateien brauchen einen anderen Leser beziehungsweise eine kontrollierte Konvertierung.
Wichtig für die Aussagekraft: Es werden keine Datenzeilen exportiert und keine fachlichen Datentypen aus Stichproben geraten. VARCHAR ist ausdrücklich ein ungeprüfter Katalog-Platzhalter. Leere, doppelte, numerische oder Formelüberschriften führen zum Fehler. Die verwendete Excel-Bibliothek kann intern gemeinsam gespeicherte Zeichenketten (Shared Strings) laden; „keine Zeilen exportiert“ bedeutet nicht „keine Inhaltsbytes im Prozessspeicher“. Eine exakte Zeilenzahl wird für Excel nicht behauptet. Für dieses Beispiel gelten Grenzen von 100 MiB entpacktem ZIP-Inhalt und 512 Spalten.
8. Praxisbeispiel: nur den QVD-Header lesen
Deine Vermutung trifft auf das dokumentierte QVD-Format zu: Vor Symboltabellen und binären Datensätzen steht ein UTF-8-XML-Header. Für ein Metadateninventar muss der Adapter diese Nutzdaten nicht dekodieren. Der Beispielparser sucht begrenzt nach </QvdTableHeader> und verarbeitet ausschließlich den XML-Teil.
python -m company_catalog.file_scanner qvd ./demo-input/qvd --output ./fixtures/qvd.json
python -m company_catalog.file_scanner qvd /freigegeben/qvd --output ./fixtures/qvd.json
Die Projektion lautet Pilot-Service → local_files → qvd → eine Tabelle je QVD-Datei. Sie übernimmt vorhandene Headerangaben: Tabellen- und Feldnamen, deklarierte Datensatzanzahl, Erstellungszeit, Format-Hinweise und Symbolanzahl je Feld. Die deklarierte Anzahl ist kein unabhängig nachgezählter Datenbestand. Qlik-Dualwerte und NumberFormat.Type sind keine eindeutige SQL-Typgarantie; deshalb bleibt der logische Typ hier ungeprüft.
Der Parser liest maximal 8 MiB bis zum Headerende, lehnt DTDs/Entities ab und dekodiert keinen Binärbereich. Ein Leseblock kann wenige binäre Bytes mit einlesen; diese werden nicht als XML verarbeitet. Unlesbare, abgeschnittene oder abweichende/verschlüsselte Formate können scheitern. Er entschlüsselt keine QVD-Dateien. Dann native Qlik-Funktionen beziehungsweise einen kontrollierten Metadatenexport verwenden. SQL- und Verbindungsinformationen aus möglichen Lineage-Headerfeldern werden bewusst nicht automatisch veröffentlicht.
Die mitgelieferte Demo-QVD ist eine Parser-Fixture: realistischer XML-Aufbau plus künstliche Binärbytes, keine in Qlik ladbare Datentabelle. Vor Produktiveinsatz zusätzlich echte, freigegebene QVDs aus der eigenen Qlik-Version prüfen.
9. Vom Scan zum OpenMetadata-Pilot
- JSON lokal prüfen: erwartete Dateien/Blätter, Spalten, Ausschlüsse und Herkunft. Auch Dateinamen und Kopfzeilen können vertraulich sein.
- Den exakt passenden OpenMetadata-SDK-Pin installieren. Excel und QVD erhalten getrennte Pilot-Services, etwa
excel_pilotundqvd_pilot, jeweils im Workflow eingestellt. - Im tatsächlich ausführenden Runner
CONNECTOR_METADATA_FILEauf das geprüfte JSON setzen; Host und Token wie oben konfigurieren. Der Scanner selbst ruft keine API auf. - Erst
metadata ingest -c workflow.yamlschreibt Metadaten. Scan und Ingestion als zwei geordnete Schritte betreiben: Ein fehlgeschlagener Scan muss den anschließenden Import eines alten JSON verhindern. - Zweimal laufen lassen und dieselben Identitäten erwarten. Gleiche Dateinamen in verschiedenen Unterordnern bleiben getrennt. Ein Umbenennen/Verschieben erzeugt in diesem Beispiel eine neue Identität; dafür ist bei Bedarf eine persistente Quell-ID-Zuordnung zu ergänzen.
Ein defektes ausgewähltes File, fehlende Leserechte oder ein leerer Trefferbestand lassen den gesamten Scan scheitern. Das bisherige JSON wird erst nach erfolgreicher Validierung atomar ersetzt. Symlinks werden nicht verfolgt und müssen explizit ausgeschlossen werden. Automatische Löschung fehlender Assets, Profiling, Owner-/Tag-Zuweisung und Lineage sind weiterhin getrennte Erweiterungen. Generierte Beschreibungen werden erneuert: fachliche manuelle Anmerkungen dort nicht unkontrolliert überschreiben lassen.
Abnahmefälle: verschachtelte Ordner, zwei gleiche Dateinamen, zwei stabile Läufe, versteckte Blätter, andere Kopfzeile, doppelte Spalten, Formelkopf, beschädigte Datei, zu großer/fehlender QVD-Header und Fehler ohne Überschreiben des vorherigen Bestands. Das Paket enthält dafür ausführbare Tests; eine Serverintegration ersetzen diese Tests nicht.