Thema: Teil 11. Datenvalidierung: validation.md
Schwierigkeitsgrad: Mittelstufe
Geschätzte Lernzeit: 2-3 Stunden
Voraussetzungen: Grundlegendes Verständnis von dbt (Modelle, Tests, schema.yml)
SQL-Kenntnisse auf dem Niveau des Schreibens von Abfragen und Singular-Tests
Vertrautheit mit den Spezifikationen ODCS und ODPS
Verständnis des Konzepts Specification-Driven Development (SDD)
Erfahrung in der Kommandozeile und beim Ausführen von dbt-Befehlen
Lernziele: Einen Prüfsachverhalt als Befehl, SQL-Abfrage oder manuellen Reviewer-Schritt formulieren und ihn von einem Wunsch unterscheiden
Sachverhalte in automatische und manuelle aufteilen und die Wahl des Typs für jeden begründen
Eine minimale validation.md für ein Datamart erstellen, die Sachverhalte zu grain, PII, Vertrag, lineage und manuellem Review enthält
Die Praxis anwenden, validation.md vor dem SQL-Code zu schreiben, um den Umfang der Lösung zu begrenzen
Mehrere Validierungsschichten (Spezifikation, ODCS, schema.yml, dbt-Tests) zu einem einzigen Validierungsartefakt verknüpfen
Übersicht: Datenvalidierung im Specification-Driven Development ist keine abstrakte Aussage „die Daten sind korrekt“, sondern eine Sammlung konkreter, ausführbarer Sachverhalte. Jeder Sachverhalt muss die Modellspezifikation, das SQL-Artefakt und einen Nachweis miteinander verbinden. Wenn ein Sachverhalt nicht per Befehl ausgeführt, mit einer SQL-Abfrage geprüft oder durch einen dokumentierten manuellen Reviewer-Schritt bestätigt werden kann, bleibt er ein Wunsch. Das Dokument validation.md hält diese Sachverhalte in einer versionsfähigen und lesbaren Form fest und verwandelt eine Datenveröffentlichung von einer Ansammlung von SQL-Patches in einen ingenieurmäßigen Prozess. In diesem Leitfaden werden die Struktur von validation.md, der minimale Satz von Sachverhalten, der Unterschied zwischen automatischen und manuellen Prüfungen sowie die Praxis behandelt, Validierung vor dem Code zu schreiben.
Schlüsselkonzepte: Prüfsachverhalt: Eine Aussage über Daten, die auf eine von drei Arten ausgeführt werden kann: durch einen Befehl (z. B. dbt test), durch einen SQL-/Singular-Test oder durch einen dokumentierten manuellen Reviewer-Schritt. Der Sachverhalt verbindet Spezifikation, SQL und Nachweis. Ohne diese Verbindung bleibt die Aussage ein Wunsch.
Automatischer Sachverhalt: Ein Prüfsachverhalt, der per Befehl ausgeführt wird und mit einem Exit-Code oder einer Zeilenmenge endet. Beispiel: dbt test --select mart_customer_360 erwartet den Exit-Code 0 und keine Fehler. Geeignet für Eigenschaften, die im Schema und in der Datenlogik formalisierbar sind: Eindeutigkeit, not_null, Wertebereiche, Formate.
Manueller Sachverhalt: Ein Prüfsachverhalt, der das Lesen einer Änderung oder eine Bestätigung durch den Produktverantwortlichen/Reviewer erfordert. Er ist dort notwendig, wo die Entscheidung vom Vertragskontext abhängt: z. B. ob das Hinzufügen eines neuen Felds zum grain des Marts zulässig ist. Ein manueller Sachverhalt ist nur dann stark, wenn explizit angegeben ist, was gelesen werden soll und welche Schlussfolgerung zu ziehen ist.
Grain des Marts: Definition dessen, was eine Zeile im Mart darstellt (z. B. eine customer_id = eine Zeile). Ein Sachverhalt zum grain ist normalerweise automatisch: Es werden Eindeutigkeit des Schlüssels und not_null geprüft. Eine Änderung des grain erfordert ein manuelles Review.
Pii-Schutz: Prüfung, dass keine direkten personenbezogenen Daten (E-Mail, Telefon, Reisepass) in das Mart gelangt sind. Umgesetzt durch einen Singular-Test, der 0 Zeilen zurückgibt, wenn PII-Felder in den Ausgabespalten des Modells vorhanden sind.
Mart-Vertrag: Liste der Pflichtfelder, ihrer Typen und Regeln, festgehalten in schema.yml und ODCS. Der Prüfsachverhalt zum Vertrag umfasst Tests auf Pflichtfelder und Typen sowie einen manuellen Sachverhalt: Eine Änderung darf die Vertragsfelder nicht ohne ausdrückliche Bestätigung verändern.
Lineage und Eingangsmodelle: Liste der Quellen, aus denen das Mart zusammengesetzt wird. Der Prüfsachverhalt hält fest, welche Modelle als Eingang dienen und ob Quellen ohne Aktualisierung der Spezifikation geändert wurden.
Sdd (specification-driven development): Ein Entwicklungsansatz, bei dem die Spezifikation vor dem Code geschrieben wird. validation.md ist eines der SDD-Artefakte, das die Spezifikation prüfbar und änderungsbeständig macht.
dbt-Singular-Test: Eine SQL-Abfrage in einer Datei tests/assert_*.sql, die Zeilen zurückgibt, wenn eine Regel verletzt wird. Ein leeres Ergebnis = Test bestanden. Wird für komplexe Prüfungen verwendet, die sich nicht durch Generic-Tests in schema.yml ausdrücken lassen.
Schwacher vs. starker Sachverhalt: Ein schwacher Sachverhalt ist eine Phrase wie „Datenqualität prüfen“ oder „sieht normal aus“. Ein starker Sachverhalt enthält einen Befehl, ein erwartetes Ergebnis und einen Status: „dbt test --select mart_customer_360 gibt Exit-Code 0 zurück, customer_id ist unique und not_null, Status: akzeptiert“.
Wichtige Termine: Konzept validation.md im SDD: Entsteht in der Entwurfsphase des Marts (mart) im Datenprojekt, vor dem Schreiben der dbt-Modelle. Die Datei wird in specs/validation/ gespeichert und gemeinsam mit Spezifikationen und Code in Git versioniert.
Zeitpunkt der Überprüfung der Sachverhalte: Bei Änderung einer der Schichten: Modellspezifikation, ODCS-Vertrag, models/schema.yml, dbt-Modelle oder Zusammensetzung der Quellen. validation.md muss explizit zeigen, welche Sachverhalte überprüft werden müssen.
Übungsaufgaben: Name: Schwachen Punkt in drei Formen umschreiben
Problem: In einer alten Release-Checkliste gibt es den Punkt „Datenqualität in mart_customer_360 prüfen“. Schreiben Sie ihn in drei Formen um: 1) dbt-Befehl mit erwartetem Ergebnis, 2) SQL/Singular-Test mit Beschreibung, was er zurückgeben soll, 3) manueller Sachverhalt des Reviewers mit Angabe, was genau zu lesen ist und welche Schlussfolgerung zu ziehen ist.
Lösung: Form 1 (dbt-Befehl):
### F1 — Schlüsselqualität
- Befehl: dbt test --profiles-dir . --select mart_customer_360
- Erwartung: Exit-Code 0; Tests customer_id unique und not_null bestehen.
- Status: akzeptiert.
Form 2 (Singular-Test):
-- tests/assert_customer_360_no_orphan_orders.sql
select c.customer_id, c.last_order_id
rom {{ ref('mart_customer_360') }} c
left join {{ ref('dim_orders') }} o on o.order_id = c.last_order_id
where c.last_order_id is not null and o.order_id is null
- Befehl: dbt test --profiles-dir . --select assert_customer_360_no_orphan_orders
- Erwartung: Der Test gibt 0 Zeilen zurück.
- Status: akzeptiert.
Form 3 (manueller Sachverhalt):
### F3 — grain-Review
Der Reviewer hat bestätigt, dass das Hinzufügen von product_code zu mart_customer_360 das grain ändern würde (eine Zeile pro customer × product statt pro customer) und nicht zur aktuellen Phase gehört. Die Entscheidung ist im Ticket DATA-1234 festgehalten.
Komplexität: beginner
Name: Minimale validation.md für ein Mart zusammenstellen
Problem: Erstellen Sie für das Mart mart_orders_summary (eine Zeile = eine order_id) eine minimale validation.md, die Folgendes enthält: Sachverhalt zum grain, Sachverhalt zu PII, Sachverhalt zu Pflichtfeldern des Vertrags, Sachverhalt zu Lineage/Eingangsmodellen und einen manuellen Sachverhalt. Modellspezifikation: models/schema.yml enthält order_id (unique, not_null), customer_id (not_null), total_amount (not_null), order_date (not_null). Quellen: stg_orders, stg_customers. PII: E-Mail, Telefon — dürfen nicht ins Mart gelangen.
Lösung: ```markdown
validation.md — mart_orders_summary
F1 — grain des Marts
- Befehl: dbt test --profiles-dir . --select mart_orders_summary
- Erwartung: order_id unique und not_null, Exit-Code 0.
- Status: akzeptiert.
F2 — keine PII im Mart
- Befehl: dbt test --profiles-dir . --select assert_orders_summary_no_pii
- Erwartung: Der Test gibt 0 Zeilen zurück (in den Ausgabespalten sind keine Felder email/phone).
- Status: akzeptiert.
F3 — Pflichtfelder des Vertrags
- Befehl: dbt test --profiles-dir . --select mart_orders_summary
- Erwartung: customer_id, total_amount, order_date — alle not_null.
- Status: akzeptiert.
F4 — Lineage und Eingangsmodelle
- Befehl: dbt list --select +mart_orders_summary --output name
- Erwartung: Die Liste enthält stg_orders und stg_customers als direkte Vorgänger.
- Status: akzeptiert.
F5 — Review der grain-Änderung
Der Reviewer hat bestätigt, dass das Hinzufügen von order_line_id zu mart_orders_summary das grain ändern würde und nicht zur MVP-Phase gehört. Die Entscheidung ist im Ticket DATA-7788 festgehalten.
Komplexität: intermediate
Name: Typischen Fehler finden und beheben
Problem: Ein Kollege hat in validation.md den Sachverhalt geschrieben: „Die Daten im Mart sind korrekt und release-bereit“. Erklären Sie, warum dies ein schwacher Sachverhalt ist, und schreiben Sie ihn in einen starken um. Hinweis: Mart mart_payments, Schlüssel payment_id, Quelle stg_payments.
Lösung: Analyse: Die Phrase „Daten sind korrekt“ ist ein Wunsch, kein Sachverhalt. Sie enthält keinen Befehl, gibt kein erwartetes Ergebnis an und kann nicht ausgeführt werden. Ein Agent könnte Korrektheit als das Fehlen von Ausführungsfehlern verstehen, ein Analyst als das Fehlen leerer Werte, ein Produktverantwortlicher als die Erhaltung des grain. Ein Sachverhalt beseitigt diese Mehrdeutigkeit nur, wenn er Befehl, Erwartung und Status enthält.
Starker Sachverhalt:
F1 — payment_id ist eindeutig und nicht leer
- Befehl: dbt test --profiles-dir . --select mart_payments
- Erwartung: Tests payment_id unique und not_null bestehen, Exit-Code 0.
- Status: akzeptiert.
Zusätzlich kann ein Sachverhalt zu Beträgen und Daten hinzugefügt werden: total_amount ≥ 0, payment_date innerhalb der letzten 90 Tage.
Komplexität: beginner
Name: Entscheiden, welcher Sachverhalt automatisiert und welcher manuell belassen wird
Problem: Für das Mart mart_customer_360 ist eine Liste von Aussagen gegeben. Geben Sie für jede an: automatischer oder manueller Sachverhalt, und begründen Sie die Wahl. Aussagen: 1) customer_id ist eindeutig; 2) im Mart gibt es keine PII-Felder; 3) das Hinzufügen von product_code würde das grain nicht verletzen; 4) total_orders ist unter Berücksichtigung aktueller Stornierungen berechnet; 5) created_at ist bei allen Zeilen gefüllt.
Lösung: 1) Automatisch — dbt test auf unique und not_null, formalisierbar.
2) Automatisch — Singular-Test, der die Liste der Modellsspalten auf das Vorhandensein von PII-Namen oder -Werten prüft.
3) Manuell — die Entscheidung über die Zulässigkeit eines neuen Felds im grain hängt vom Vertrag und der Phase ab und erfordert das Lesen der Spezifikation sowie die Bestätigung des Verantwortlichen.
4) Automatisch (teilweise) — Singular-Test, der total_orders mit der Aggregation aus der Quelle vergleicht und prüft, ob Stornierungen berücksichtigt sind. Zusätzlich manueller Sachverhalt: Der Reviewer hat die Logik der Stornierungsbehandlung im Modellcode bestätigt.
5) Automatisch — Generic-Test not_null auf die Spalte created_at.
Komplexität: intermediate
Name: Validierungsschichten in einem Sachverhalt verknüpfen
Problem: Beschreiben Sie, wie ein Prüfsachverhalt die Modellspezifikation (specs/models/mart_customer_360.md), ODCS, models/schema.yml, Singular-Test und Reviewer-Bericht miteinander verbindet. Zeigen Sie, was mit dem Sachverhalt passiert, wenn sich eine der Schichten ändert.
Lösung: Beispiel für den Sachverhalt „customer_id ist eindeutig und nicht leer“:
- Die Spezifikation legt das grain und die Liste der Pflichtfelder fest.
- ODCS beschreibt customer_id als Pflichtfeld vom Typ string.
- models/schema.yml enthält Tests unique und not_null auf customer_id.
- Der Singular-Test prüft zusätzlich, dass customer_id nach allen Joins nicht NULL ist (Schutz vor LEFT JOIN mit NULL auf der rechten Seite).
- Der Reviewer-Bericht hält fest, dass die Tests in CI bestanden haben und der Status des Sachverhalts „akzeptiert“ ist.
Wenn sich die Spezifikation ändert (z. B. wird grain zu customer × product), erfordern alle vier Schichten eine Überprüfung: ODCS wird geändert, in schema.yml wird die Eindeutigkeit auf den zusammengesetzten Schlüssel verlagert, der Singular-Test wird aktualisiert, der Reviewer überprüft den Sachverhalt erneut. validation.md muss explizit angeben, welche Sachverhalte überprüft wurden.
Komplexität: advanced
Fallstudien:
Name: Release des Marts Customer 360: Wie validation.md vor einem PII-Leak schützte
Szenario: Das Analytics-Team bereitete das Release des Marts mart_customer_360 für das Marketing vor. Das Mart wurde aus stg_customers (enthält E-Mail und Telefon) und stg_orders zusammengesetzt. In das Code-Review geriet nicht die Bedingung, und das Feld E-Mail blieb versehentlich im Ausgabeergebnis erhalten. Die Modellspezifikation verbot direkte PII im Mart ausdrücklich.
Aufgabe: Ohne formelle Prüfung existierte der Sachverhalt „keine PII im Mart“ nur im Kopf des Analysten. Der Agent wertete das Release aufgrund des Exit-Codes von dbt run als erfolgreich, der Analyst aufgrund fehlender leerer Werte, der Produktverantwortliche aufgrund der Erhaltung des grain. Niemand prüfte die Zusammensetzung der Spalten.
Lösung: Das Team führte validation.md als verbindliches Release-Artefakt ein. Für mart_customer_360 wurde der Sachverhalt F2 mit dem Singular-Test assert_customer_360_no_direct_pii geschrieben, der die Liste der Modellsspalten mit der Liste der verbotenen PII-Felder verglich. Der Test wurde mit dem Befehl dbt test --select assert_customer_360_no_direct_pii ausgeführt und musste 0 Zeilen zurückgeben. Der Sachverhalt wurde in die Release-Checkliste aufgenommen und blockierte das Deployment bei einem Fehler.
Ergebnis: Beim nächsten Versuch, E-Mail ins Mart einzuschleusen, fiel der Test bereits in CI aus, der Reviewer sah die Verletzung des Sachverhalts F2 und wies den Merge ab. PII gelangte nicht ins Marketing-Mart. Der Release-Prozess wurde reproduzierbar: Der Sachverhalt kann jederzeit erneut ausgeführt werden und liefert dieselbe Antwort.
Gewonnene Erkenntnisse:
Der Sachverhalt „keine PII im Mart“ ohne Befehl und erwartetes Ergebnis ist ein Wunsch, keine Prüfung.
Singular-Tests schützen vor Regressionen, die in Generic-Tests von schema.yml nicht sichtbar sind.
validation.md muss ein versionsfähiges Artefakt sein, kein Chat-Eintrag.
Verwandte Konzepte:
PII-Schutz
dbt-Singular-Test
Prüfsachverhalt
Manueller und automatischer Sachverhalt
Name: Grain-Änderung ohne Validierung: Wie ein Monat Berichtswesen verloren ging
Szenario: Ein Analyst fügte dem Mart mart_sales das Feld product_sku hinzu, damit das Dashboard Verkäufe nach Produkten anzeigen konnte. Die Änderung passierte das Code-Review, Tests not_null und Eindeutigkeit auf order_id blieben grün. Zwei Wochen später stellte die Finanzabteilung fest, dass sich der Umsatz verdoppelt hatte: Das grain des Marts war tatsächlich order_id × product_sku, obwohl Name und Tests sagten, dass das grain order_id sei.
Aufgabe: Im Projekt gab es keine validation.md. Die Tests prüften nur Spalteneigenschaften, hielten aber nicht den Sachverhalt fest, dass „das grain des Marts eine order_id = eine Zeile“ ist. Niemand hielt explizit fest, dass das Hinzufügen von product_sku das grain ändert. Der Reviewer erhielt keinen Hinweis, worauf zu achten sei.
Lösung: Nach dem Vorfall führte das Team eine verbindliche validation.md für jedes Mart ein. Für mart_sales entstand der Sachverhalt F1 (grain: order_id unique und not_null) und der manuelle Sachverhalt F5: „Der Reviewer hat bestätigt, dass die Änderung die Vertragsfelder und das grain nicht ohne ausdrückliche Bestätigung des Verantwortlichen verändert“. Im Ticket zum Hinzufügen von product_sku hätte der manuelle Sachverhalt eine ausdrückliche Entscheidung verlangt: Entweder das grain und den Namen des Marts ändern oder product_sku in eine separate Schicht auslagern.
Ergebnis: Drei Monate später schlug das Team vor, das Feld channel ins Mart aufzunehmen. Der Reviewer las validation.md, sah den Sachverhalt F5 und stoppte den Merge, wobei er eine separate Entscheidung zum grain anforderte. Die Release-Zeit verkürzte sich, weil das Review anhand einer Rubrik und nicht nach Intuition erfolgte.
Gewonnene Erkenntnisse:
Eindeutigkeit des Schlüssels ist nicht dasselbe wie ein festgelegtes grain. Grain ist ein Vertrag, der auch manuell geprüft werden muss.
validation.md wird vor dem SQL geschrieben: Sie begrenzt den Umfang der Lösung und gibt Hinweise, welche Tests nötig sind.
Wenn validation.md nach dem SQL geschrieben wird, wird sie zur Rechtfertigung des bereits Getanen, nicht zum Schutz des Releases.
Verwandte Konzepte:
Grain des Marts
Manueller Sachverhalt
Mart-Vertrag
SDD
Name: Lineage als Prüfsachverhalt: Aufdecken einer stillen Quellenänderung
Szenario: Das Plattform-Team aktualisierte das Schema in stg_orders und benannte die Spalte order_total in order_total_amount um. Die dbt-Modelle mart_sales bauten sich weiterhin auf, Tests bestanden, weil im Code ref() verwendet wurde und die Anpassung an den neuen Namen automatisch über die Variablenumbenennung erfolgte. Doch das Mart mart_sales_weekly brach: Eines der Downstream-Dashboards zeigte Nullen, weil darin ein hartcodiertes SELECT mit dem alten Namen verwendet wurde.
Aufgabe: Generic-Tests fielen nicht aus, weil mart_sales_weekly aus einem Zwischenmodell aufgebaut wurde, in dem die Spalte bereits umbenannt war. Es gab keinen Sachverhalt, der die Zusammensetzung der Eingangsmodelle und deren Schema festhielt. Der Reviewer erhielt kein Signal, dass sich die Quelle geändert hatte.
Lösung: Das Team fügte in validation.md für jedes Mart den Sachverhalt F4 zur Lineage hinzu: Der Befehl dbt list --select +<mart> --output name hält die Liste der Vorgänger fest. Zusätzlich wurden Singular-Tests eingeführt, die das Vorhandensein von Pflichtspalten in der Quelle prüfen (information_schema). Bei einer Umbenennung in stg_orders wäre ein solcher Test in der Build-Phase des Marts ausgefallen, und der Reviewer hätte die Verletzung des Sachverhalts F4 gesehen.
Ergebnis: Nach einem Quartal bemerkte das Team den Versuch, das Feld customer_segment in stg_customers zu löschen. Der Test auf das Vorhandensein der Spalte in der Quelle fiel aus, der Sachverhalt F4 in validation.md wurde als überprüfungspflichtig markiert, die Änderung gelangte nicht ohne ausdrückliche Entscheidung in main.
Gewonnene Erkenntnisse:
Lineage ist Teil des Vertrags. Änderungen an der Zusammensetzung oder dem Schema der Quellen müssen in validation.md sichtbar sein.
Automatische Tests auf information_schema schützen vor stillen Umbenennungen, die Generic-Tests nicht brechen.
validation.md verbindet mehrere Schichten: Spezifikation, ODCS, schema.yml, Singular-Tests und Review.
Verwandte Konzepte:
Lineage und Eingangsmodelle
dbt-Singular-Test
Prüfsachverhalt
Mart-Vertrag
Lerntipps:
Schreiben Sie validation.md vor dem SQL. Formulieren Sie zuerst die Sachverhalte (grain, PII, Vertrag, Lineage, manuelles Review), dann die Tests und das Modell. Dies reduziert den Umfang der Lösung und macht das Review strukturiert.
Bewahren Sie validation.md in Git zusammen mit Spezifikationen und Code auf. Eine Datei im Chat oder im Wiki kann kein Nachweis für ein Release sein.
Verwandeln Sie jeden schwachen Punkt der Checkliste in einen starken Sachverhalt: Fügen Sie Befehl, erwartetes Ergebnis und Status hinzu. Die Phrase „sieht normal aus“ ist kein Sachverhalt.
Versuchen Sie nicht, alles zu automatisieren. Entscheidungen, die vom Vertrag abhängen (z. B. was als aktiver Kunde gilt), belassen Sie als manuelle Sachverhalte mit Angabe, was genau zu lesen ist und welche Schlussfolgerung zu ziehen ist.
Verwenden Sie Singular-Tests für Prüfungen, die sich nicht durch Generic-Tests ausdrücken lassen: Spaltenzusammensetzung, Datumsbereiche, Fehlen von PII, referenzielle Integrität nach Joins.
Gehen Sie bei Änderungen einer Schicht (Spezifikation, ODCS, schema.yml, Modell, Quelle) validation.md durch und markieren Sie die Sachverhalte, die überprüft werden müssen.
Verwenden Sie Qwen (oder ein anderes LLM) für den Entwurf von validation.md, indem Sie ihm Links zu specs/models/, ODCS, ODPS und models/schema.yml übergeben. Bitten Sie das LLM nicht, dbt-Modelle zu ändern — nur Validierungssachverhalte zu generieren.
Fügen Sie validation.md zur Pull-Request-Checkliste hinzu: Der Reviewer muss die Datei vor der Änderung lesen und markieren, welche Sachverhalte überprüft wurden.
Unterscheiden Sie zwischen grain (Vertrag) und Eindeutigkeit des Schlüssels (Test). Eindeutigkeit kann automatisch geprüft werden, eine Änderung des grain nur manuell mit Bestätigung des Verantwortlichen.
Minimaler Satz von Sachverhalten für ein Mart: einer zum grain, einer zu PII, einer zu Pflichtfeldern des Vertrags, einer zur Lineage, ein manueller zur Unveränderlichkeit des Vertrags ohne Bestätigung.
Zusätzliche Ressourcen:
Dbt-Dokumentation — Tests: https://docs.getdbt.com/docs/build/tests — offizielle Dokumentation zu Generic- und Singular-Tests in dbt.
Dbt-Dokumentation — Singular-Tests: https://docs.getdbt.com/docs/build/singular-tests — Leitfaden zum Schreiben von Singular-Tests in SQL.
Odcs (open data contract standard): https://bitol-io.github.io/open-data-contract-spec/ — Datenvertragsstandard, der mit validation.md verknüpft wird.
Odps (open data product standard): https://opendataproducts.org/ — Datenproduktstandard, der im SDD als eine der Spezifikationsschichten verwendet wird.
Specification-driven development für Datenprojekte: Konzept des SDD, in dem validation.md ein verbindliches Release-Artefakt ist, kein optionales Dokument.
Dbt-utils-Paket: https://github.com/dbt-labs/dbt-utils — Paket mit fertigen Tests (expression_is_true, accepted_range, relationships u. a.), die in validation.md verwendet werden können.
Zusammenfassung: validation.md ist der Ort, an dem das SDD-Lehrbuch streng wird. Ein Prüfsachverhalt unterscheidet sich von einem Wunsch dadurch, dass er ausführbar ist: durch einen Befehl (dbt test), einen SQL/Singular-Test oder einen dokumentierten manuellen Reviewer-Schritt. Eine minimale validation.md für ein Mart enthält fünf Sachverhalte: grain, PII-Schutz, Pflichtfelder des Vertrags, Lineage/Eingangsmodelle und einen manuellen Sachverhalt zur Unveränderlichkeit des Vertrags ohne Bestätigung. Nicht alle Sachverhalte müssen automatisiert werden — Entscheidungen, die vom Vertrag abhängen (z. B. die Zulässigkeit eines neuen Felds im grain), bleiben manuell. validation.md verbindet mehrere Schichten: Modellspezifikation, ODCS, models/schema.yml, Singular-Tests und Reviewer-Bericht. Bei Änderung einer Schicht muss die Datei explizit zeigen, welche Sachverhalte überprüft werden müssen. Die wichtigste Praxis: Schreiben Sie validation.md vor dem SQL — das begrenzt den Umfang der Lösung, gibt Hinweise auf die nötigen Tests und liefert dem Reviewer eine fertige Rubrik. Wenn validation.md nach dem SQL geschrieben wird, wird sie zur Rechtfertigung des bereits Getanen, nicht zum Schutz des Releases.