Data Quality
Kurzzusammenfassung
- Diese Seite beschreibt das DQ-Gate im Gesamtprozess: wie Datenqualität gemessen wird, wie daraus ein Status entsteht und wie dieser Status das Routing im BPMN steuert (
DQ OK?→ Downstream oder Quarantine). - Die DQ-Checks sind bewusst pragmatisch gehalten: Schema-Konformität, Vollständigkeit, Schlüssel-/Duplikat-Regeln, zeitliche Plausibilität und wenige Domain-Plausibilitäten pro Datensatztyp.
- Ergebnis pro Ingestion-Run ist ein DQ-Report (
dq_report_uri) plusquality_statusim Validated Curated Dataset Contract. Dieser Status wird zusätzlich in OpenMetadata am Dataset (und idealerweise auf Partition/Run-Ebene) sichtbar gemacht. - BPMN-Leitpfad (Main):
Purpose + Entitlement Check (Gate A)→Quality Gate (Regeln)→ GatewayDQ OK?→Pass(Downstream) oderFail(Quarantine + Review/Exception).
Einordnung: Das DQ-Gate ist Schritt 4 in der Gesamtarchitektur und baut auf Scheduling, Ingestion (Data Pipeline: ELT + Validierung) und Purpose + Entitlement Check (Gate A) auf.
Ziel
- Klare, wiederholbare Qualitätsregeln pro Dataset-Typ, die sich im Betrieb bewähren (nicht zu komplex, aber wirksam).
- Ein eindeutiger DQ-Status pro Run/Partition, der Downstream-Pipelines steuert und im Katalog nachvollziehbar ist.
- Ein einfacher Umgang mit Ausnahmen: DQ-Fail führt standardmässig zu Quarantine; Ausnahmen sind möglich, aber bewusst selten und dokumentiert.
Scope & Abgrenzung
In Scope (diese Seite):
- DQ-Regeln (Regelklassen, Severity, Schwellen)
- Status-Mapping (
PASS/WARN/FAIL) und Gate-Entscheid (Pass/Fail im BPMN) - DQ-Artefakte (
dq_report_uri, Summary-Metriken) und Katalogisierung in OpenMetadata - Quarantine-Pfad und pragmatische Exception-Logik (wie im BPMN vorgesehen)
Out of Scope (separate Seiten / BPMN-Schritte):
- Ingestion-Implementierung (Extract/Load/Transform/Validate) →
Data Pipeline - Scheduling und Zeitzonen-Planung →
Scheduling - Incidents/Runbooks →
Incident ManagementundFailure Handling - Feature Engineering / Labels / Training / Backtesting → jeweilige ML-Lifecycle-Seiten
Inputs fürs DQ-Gate
1) Validated Curated Dataset Contract
Das DQ-Gate bezieht sich auf den Contract, der aus der Data Pipeline kommt. Relevante Felder sind unter anderem:
dataset_id,dataset_versionas_of_daterun_id(Prefect Flow Run ID)schema_version,schema_hashquality_statusrow_countdq_report_uriopenmetadata_entity_ref(Verknüpfung Dataset/Entity im Katalog)
Siehe: Ingestion (Data Pipeline)
2) Gate-A Ergebnisse / Katalog-Metadaten
Vor dem DQ-Gate ist Gate A gelaufen. Damit sind die Minimal-Metadaten für Nutzung und Ownership gesetzt (Owner, Purpose/Allowed Use, Klassifikation, Retention usw.). Das DQ-Gate setzt darauf auf und ergänzt den Qualitätsstatus.
Siehe: Purpose + Entitlement Check (Gate A)
Output des DQ-Gates
Pro Run/Partition entstehen:
quality_statusim Contract (Werte:PASS,WARN,FAIL)- ein versionierter DQ-Report (URI im Contract:
dq_report_uri) - eine Aktualisierung in OpenMetadata (Status + Verlinkung auf Report/Run)
Für das BPMN-Routing gilt:
dqPassed = true, wennquality_status ∈ {PASS, WARN}dqPassed = false, wennquality_status = FAIL
Damit bleibt der Gateway-Knoten DQ OK? im Main-BPMN konsistent (Pass/Fail), während WARN als «pass with flag» gehandhabt wird.
DQ-Statusmodell
Severity
Damit Checks handhabbar bleiben, nutzen wir zwei Schweregrade:
CRITICAL→ ein Fail führt zuquality_status = FAILWARNING→ ein Fail führt zuquality_status = WARN(solange kein Critical failt)
Statusregeln
PASS: alle Critical-Checks ok, alle Warning-Checks okWARN: alle Critical-Checks ok, mindestens ein Warning-Check verletztFAIL: mindestens ein Critical-Check verletzt
Das Statusmodell ist deterministisch und lässt sich gut automatisieren und testen.
DQ-Regelklassen
Die Regelklassen sind absichtlich generisch (und damit für mehrere Datasets wiederverwendbar). Konkrete Checks pro Dataset-Gruppe folgen weiter unten.
| Regelklasse | Was wird geprüft | Typisches Beispiel | Severity (Default) |
|---|---|---|---|
| Schema | Pflichtfelder und Datentypen | symbol fehlt, date nicht parsebar | CRITICAL |
| Uniqueness | Keine Duplikate auf Schlüssel | Doppelte (symbol, date) | CRITICAL |
| Completeness | Missing-Rate in kritischen Feldern | close / volume Null-Rate | CRITICAL oder WARNING (je Feld) |
| Referential / IDs | Identifier gültig und konsistent | unbekannte Symbole / leere CIK | WARNING/CRITICAL (je Dataset) |
| Temporal Plausibility | Datum/Partition passt zu as_of_date | Daten in der Zukunft, falsche Partition | CRITICAL |
| Domain Plausibility | einfache Wertebereiche | Preise > 0, High ≥ Low | CRITICAL/WARNING |
| Drift-Indikatoren | grobe Anomalie-Signale | plötzlicher Sprung in Coverage | WARNING |
Datasets im Projekt und erwartete Cadence
Die Cadence richtet sich nach dem langfristigen Stock-Picking-Setup (EOD + regelmässige Refreshes). Details siehe Scheduling.
| Dataset-Gruppe | Quellen | Cadence | Typische Partition |
|---|---|---|---|
| EOD Prices (EU/US) | FMP API | Mo–Fr | as_of_date |
| Macro | FRED API + FMP API | Mo–Fr | as_of_date |
| Filings / Events | SEC EDGAR + FMP API | Mo–Fr | as_of_date |
| Fundamentals Refresh | FMP API | wöchentlich (Mo) | Snapshot-Datum |
Checks pro Dataset-Gruppe
Die folgenden Checks sind als Beispiel-Suite angelegt.
EOD Prices
Schlüssel:
symbol,as_of_date
Checks:
- Schema: Pflichtfelder vorhanden (mind.
symbol,date,open,high,low,close, optionalvolume) - Uniqueness: keine Duplikate auf
(symbol, date) - Completeness:
closemissing → CRITICALopen/high/lowmissing → WARNING (je nach Providerqualität)
- Domain:
close > 0(CRITICAL)high >= low(CRITICAL)closeliegt zwischenlowundhigh(WARNING, weil manche Provider Rundungs-/Timing-Artefakte haben)
- Temporal:
datedarf nicht in der Zukunft liegen (CRITICAL)- Partition passt zu
as_of_date(CRITICAL)
- Coverage (einfach):
- Coverage-Drop gegenüber letzter erfolgreicher Partition > X % → WARNING
Macro
Schlüssel:
series_id,date
Checks:
- Schema:
series_id,date,value - Uniqueness:
(series_id, date)eindeutig - Completeness:
valuemissing → WARNING (einzelne Serien können sporadisch fehlen)
- Temporal:
- keine zukünftigen Werte, Partition passt (CRITICAL)
- Domain (leicht):
- Werte sind numerisch (CRITICAL)
- optional: sehr grobe Range-Guards pro Serie (WARNING)
Filings / Events
Schlüssel:
entity_id(z. B. CIK),filing_date/event_date,form_type
Checks:
- Schema: Pflichtfelder (
cik,form_type,filing_date,document_url/accession_no) - Completeness:
cikoderform_typemissing → CRITICALdocument_urlmissing → WARNING (je nach Use)
- Temporal:
filing_dateplausibel (nicht in Zukunft) (CRITICAL)
- Parse-Qualität (pragmatisch):
- wenn Parsing vorgesehen ist: Anteil
parse_failed≤ Schwelle → WARNING/FAIL (je nach Abhängigkeit)
- wenn Parsing vorgesehen ist: Anteil
Fundamentals Refresh
Schlüssel:
symbol,period_endoderreport_date(je nachdem, wie partitioniert wird)
Checks:
- Schema: Pflichtfelder (
symbol,report_date/period_end, zentrale Felder wierevenue,netIncomeje nach Modellbedarf) - Uniqueness:
(symbol, period_end)eindeutig - Completeness:
- fehlende Kernfelder > Schwelle → WARNING/FAIL
- Temporal:
period_endnicht in Zukunft (CRITICAL)
- Konsistenz:
- Quartal/Jahr-Labels passen zu Datum (WARNING)
Ablauf im Main-BPMN und in der Praxis
| BPMN-Element | Zweck | Praktische Umsetzung |
|---|---|---|
CallActivity_DataPipeline | Daten laden, technisch harmonisieren, validieren | Prefect Flow erzeugt Curated Dataset + Contract + DQ-Report |
CallActivity_PurposeGate (Gate A) | Allowed Use / Owner / Klassifikation prüfen | OpenMetadata-Metadaten werden geprüft/gesetzt |
CallActivity_QualityGate | DQ-Status bewerten und veröffentlichen | quality_status + dq_report_uri werden im Katalog verlinkt; dqPassed wird abgeleitet |
Gateway_DQDecision (DQ OK?) | Routing Pass/Fail | Pass: Downstream; Fail: Quarantine + Review/Exception |
Wichtig: Die DQ-Checks selbst laufen technisch in der Data Pipeline (Validierungs-Step). Das «Quality Gate» ist der dokumentierte Standard und die Stelle, an der der Status als Gate-Signal für Downstream festgezogen wird (inkl. Katalog-Update).
Quarantine und Exception-Pfad
Wenn quality_status = FAIL:
- Dataset/Partition wird in die
Quarantineüberführt (oder als quarantined markiert, je nach Storage-Setup). - Prefect Run wird als failed/blocked sichtbar; ein Ticket/Incident wird erstellt (Details:
Incident Management). - Manuelle Prüfung (im BPMN:
Manual Data Review / Exception?).
Exception (selten, aber vorgesehen):
- Wenn die Abweichung verstanden ist und Downstream-Nutzung vertretbar ist, kann die Exception im BPMN-Pfad freigegeben werden (
Exception approved?→ Override → Feature Pipeline). - Jede Exception referenziert mindestens den Run (
run_id) und den DQ-Report (dq_report_uri) sowie eine kurze Begründung.
Umsetzung in Prefect
Wo die Regeln liegen
Einfaches Muster:
dq/suites/<dataset_group>.yaml(Regeln + Schwellwerte, versioniert im Repo)flows/data_pipeline.pyführt beiServiceTask_Validatedie Suite aus- Report wird als JSON gespeichert (Artefakt/Evidence Store) und im Contract referenziert
Beispiel (vereinfachtes YAML-Schema):
# dq/suites/eod_prices.yaml
suite_version: "2026-02-18"
checks:
- name: "schema_required_columns"
severity: "CRITICAL"
params:
required: ["symbol", "date", "open", "high", "low", "close"]
- name: "unique_key"
severity: "CRITICAL"
params:
key: ["symbol", "date"]
- name: "close_positive"
severity: "CRITICAL"
params:
column: "close"
min: 0.0
- name: "close_between_low_high"
severity: "WARNING"
params:
close: "close"
low: "low"
high: "high"
DQ-Report Format
Der Report ist bewusst maschinenlesbar (für Gate + Katalog), aber kurz genug, um ihn im Alltag zu nutzen:
{
"run_id": "prefect-flow-run-3f2c8d",
"dataset_id": "eod_prices_us",
"dataset_version": "2026-02-12T23:59Z",
"as_of_date": "2026-02-12",
"dq_suite_version": "2026-02-18",
"summary": {
"quality_status": "WARN",
"checks_total": 4,
"checks_failed": 1,
"row_count": 18234567
},
"checks": [
{ "name": "schema_required_columns", "severity": "CRITICAL", "passed": true },
{ "name": "unique_key", "severity": "CRITICAL", "passed": true },
{ "name": "close_positive", "severity": "CRITICAL", "passed": true },
{
"name": "close_between_low_high",
"severity": "WARNING",
"passed": false,
"details": { "violations": 124 }
}
]
}
Im Contract wird darauf verwiesen via dq_report_uri, und quality_status wird aus summary.quality_status übernommen.
OpenMetadata: was wird gepflegt
Für die Gate-Nutzung reicht ein Minimal-Set an DQ-Informationen am Dataset:
dq_status(PASS/WARN/FAIL)dq_suite_version- Link/URI zum Report (
dq_report_uri) - Referenz auf den Run (
run_id) und die aktuelledataset_version
Optional, aber praktisch:
- kurze
results_summary(z. B. failed checks count,row_count) - Tags/Labels für
WARN(damit Warn-Phasen schnell gefunden werden)
Ziel ist kein DQ-Overengineering, sondern eine saubere, zentrale Sichtbarkeit im Katalog.
Entscheidungskriterien
Ein Run gilt im Sinne des Gate-Signals als freigegeben, wenn:
quality_status ∈ {PASS, WARN}- der DQ-Report vorhanden ist (
dq_report_uri) und zur gleichendataset_versionpasst - die Suite-Version im Report gesetzt ist (
dq_suite_version) und zur Code-Version nachvollziehbar ist
Ein Run wird blockiert (Quarantine), wenn:
quality_status = FAIL(mindestens eine Critical-Regel verletzt)- oder der Report fehlt/inkonsistent ist (z. B. falsche
dataset_version)
BPMN Detailansicht
Glossar-Begriffe
DQ– Datenqualitätsmessung und StatusOpenMetadata– Katalog/Metadaten/LineagePrefect– Orchestrierung der RunsData Pipeline– technische Ingestion/Harmonisierung/Validierung als Quelle für das DQ-GateQuarantine– isolierte Zone für Datensätze aus Fail-Runs
BPMN-Kontext
- Main BPMN: Gesamtarchitektur
- Knoten:
CallActivity_QualityGate(Quality Gate),Gateway_DQDecision(DQ OK?) - Upstream:
CallActivity_PurposeGate(Gate A),CallActivity_DataPipeline - Downstream:
- Pass:
CallActivity_FeaturePipeline - Fail:
ServiceTask_Quarantine→Create Incident / Ticket→Manual Data Review / Exception?→Exception approved?
- Pass: