Datenkontrakte in der Praxis
Fortschritt
0%
ende
Los geht’s
  • Willkommen15′
  • Setup20′
Teil A · Das Quell-Datenprodukt
  • 1.Daten unter Vertrag nehmen60′
  • 2.Evolution von Datenkontrakten30′
  • 3.Datenprodukt beschreiben20′
Teil B · Das Consumer-Aligned Data Product
  • 4.Contract-first entwerfen30′
  • 5.Datenprodukt implementieren25′
  • 6.Consumer-driven Contracts30′
Teil C · Automatisieren
  • 7.CI/CD mit GitHub Actions45′
Teil D · Datenplattformoptional
  • 8.Auf Entropy Data veröffentlichen40′
  • 9.Semantik25′
Abschluss
  • Abschluss10′
Teil B · Das Consumer-Aligned Data Product

Übung 6 · Consumer-driven Contracts

Abhängigkeiten mit einem Consumer-driven Contract explizit machen.

~30 Min.0 von 9 Schritten erledigt
Zurück
Datenprodukt implementieren
Weiter
CI/CD mit GitHub Actions
Gepflegt vonEntropy Data

Deine View aus der vorigen Übung liest direkt die Tabellen des Produzenten. Sie hängt implizit vom gesamten orders_v2-Kontrakt ab, braucht aber nur fünf Felder. Das Orders-Team kann nicht erkennen, ob eine Änderung dich bricht.

Mach die Abhängigkeit explizit: ein Consumer-driven Contract für genau die Felder, die du brauchst, und Views, die nur diese Felder bereitstellen.

Das lernst du
  • Consumer-driven Data Contracts verstehen
  • Einen Kontrakt schreiben, der nur enthält, was ein Konsument nutzt
  • Dein Datenprodukt mit Zugriffs-Views von den Tabellen des Produzenten entkoppeln
  • Prüfen, dass deine eigenen Konsumenten nicht betroffen sind
Consumer-driven Contracts

Der Konsument legt fest, welchen Ausschnitt der Daten er braucht und welche Qualität er erwartet. Die Idee stammt aus dem API-Testing (z. B. Pact): Der Produzent führt die Kontrakte aller Konsumenten in seiner eigenen Pipeline aus. So weiß er, welche Felder genutzt werden, und kann alles andere frei ändern.

Teil ATeil BSource-aligned DatenproduktOrdersOrder Data Team · PostgreSQLorders_v1 (veraltet)orders_v2Input-Ports zur Vereinfachung weggelassenKontrakt: orders_v2_consumer_sku_salesConsumer-aligned DatenproduktSKU SalesPurchasing Analytics Team · SQL viewsku_sales_per_yearData ConsumerEinkaufsteamverhandelt mit Lieferanten
In dieser Übung: ein Consumer-driven Contract mit genau den Feldern, die SKU Sales aus orders_v2 braucht.

Festlegen, was du brauchst

Kontrakt des Produzenten kopieren

Kopiere den orders_v2-Kontrakt und öffne die Kopie im Editor:

cp orders_v2.odcs.yaml orders_v2.consumer_sku_sales.odcs.yaml
datacontract edit orders_v2.consumer_sku_sales.odcs.yaml
Editing: /Users/you/learn.datacontract.com/orders_v2.consumer_sku_sales.odcs.yaml
Data Contract Editor running at http://localhost:4243
Press Ctrl+C to stop

Setze die ID auf orders_v2_consumer_sku_sales. Lass die Version bei 2.0.0, da der Kontrakt auf den v2-Daten basiert.

Auf das Genutzte reduzieren

Entferne alle Properties, die deine View nicht nutzt, samt ihren Quality Checks. Behalte nur:

  • orders: order_id, order_timestamp
  • line_items: order_id, sku, quantity

Behalte den Check quantity > 0. Dein Datenprodukt verlässt sich darauf: Sonst könnte total_quantity kleiner als order_count sein.

Die Kopie enthält auch context und synonyms des Produzenten (ODCS 3.2). Entferne den context auf Kontrakt-Ebene: Seine Verified Statements fragen order_total und die Tabellen des Produzenten ab, und sein Constraint betrifft ein Feld, das du entfernt hast. Kontext und Synonyme auf Schema-Ebene für behaltene Felder dürfen bleiben.

Mach ihn zu deinem Kontrakt

Das ist jetzt dein Kontrakt, nicht der des Orders-Teams:

  • setze team und support auf das Purchasing-Analytics-Team (wie in deinem sku_sales_per_year-Kontrakt),
  • formuliere description.purpose neu, z. B. „The fields the SKU Sales data product actually needs from orders_v2“.
Auf die Zugriffs-Views zeigen

Deine Zugriffs-Views liegen in einem neuen Schema sku_sales_input:

  • ändere das Schema des Servers auf sku_sales_input,
  • setze den physicalType beider Schema-Objekte auf VIEW,
  • falls der Check quantity > 0 eine SQL-Query ist, ändere darin orders_v2. in sku_sales_input.. Sonst testet er weiter die alten Tabellen.
Tests ausführen: wieder rot
datacontract test orders_v2.consumer_sku_sales.odcs.yaml
Testing orders_v2.consumer_sku_sales.odcs.yaml
Server: postgres (type=postgres, host=localhost, port=5433, database=workshop, 
schema=sku_sales_input)
╭────────┬───────────────────────────────┬────────────────────────┬────────────────────────────────╮
│ Result │ Check                         │ Field                  │ Details                        │
├────────┼───────────────────────────────┼────────────────────────┼────────────────────────────────┤
│ failed │ Check that field 'order_id'   │ line_items.order_id    │ Could not read model           │
│        │ is present                    │                        │ 'line_items': line_items       │
…
🔴 data contract is invalid, found the following errors:
1) 7 checks on orders.order_id, orders.order_timestamp: Could not read model 'orders': orders
2) 9 checks on line_items.order_id, line_items.sku, line_items.quantity: Could not read model 
'line_items': line_items

Sie schlagen fehl, weil es die Views noch nicht gibt. Contract-first, schon wieder.

Zugriffs-Views anlegen

Views anlegen

Lege sql/sku_sales_input.sql mit Views an, die nur die vereinbarten Felder bereitstellen:

sku_sales_input.sql
CREATE SCHEMA IF NOT EXISTS sku_sales_input;

CREATE OR REPLACE VIEW sku_sales_input.orders AS
SELECT order_id, order_timestamp FROM orders_v2.orders;

CREATE OR REPLACE VIEW sku_sales_input.line_items AS
SELECT order_id, sku, quantity FROM orders_v2.line_items;

Wende sie an:

docker compose exec -T postgres psql -U workshop -d workshop < sql/sku_sales_input.sql
CREATE SCHEMA
CREATE VIEW
CREATE VIEW
Tests ausführen: grün
datacontract test orders_v2.consumer_sku_sales.odcs.yaml
Testing orders_v2.consumer_sku_sales.odcs.yaml
Server: postgres (type=postgres, host=localhost, port=5433, database=workshop, 
schema=sku_sales_input)
╭────────┬──────────────────────────────────────────────────────┬────────────────────────┬─────────╮
│ Result │ Check                                                │ Field                  │ Details │
├────────┼──────────────────────────────────────────────────────┼────────────────────────┼─────────┤
│ passed │ Check that field 'order_id' is present               │ line_items.order_id    │         │
│ passed │ Check that field order_id has physical type text     │ line_items.order_id    │         │
│ passed │ Check that field order_id has no missing values      │ line_items.order_id    │         │
│ passed │ Check that field 'quantity' is present               │ line_items.quantity    │         │
│ passed │ Check that field quantity has physical type bigint   │ line_items.quantity    │         │
│ passed │ Ensure quantity is positive                          │ line_items.quantity    │         │
…
│ passed │ Check that field 'order_timestamp' is present        │ orders.order_timestamp │         │
╰────────┴──────────────────────────────────────────────────────┴────────────────────────┴─────────╯
🟢 data contract is valid. Run 16 checks. Took 0.545395 seconds.

Dein Datenprodukt umstellen

Aus den Zugriffs-Views lesen

Ändere sql/sku_sales_per_year.sql, sodass die View aus sku_sales_input.orders und sku_sales_input.line_items liest statt aus den orders_v2-Tabellen. Wende sie erneut an:

docker compose exec -T postgres psql -U workshop -d workshop < sql/sku_sales_per_year.sql
NOTICE:  schema "analytics" already exists, skipping
CREATE SCHEMA
CREATE VIEW
Hinweis

sql/sku_sales_per_year.sql hängt jetzt von sql/sku_sales_input.sql ab, wende also zuerst die Input-Views an. Die CI-Pipeline in Teil C macht genau das.

Prüfen, dass deine Konsumenten nicht betroffen sind

Die Ausgabe deines Datenprodukts darf sich nicht ändern. Dein eigener Kontrakt beweist es:

datacontract test sku_sales_per_year.odcs.yaml
Testing sku_sales_per_year.odcs.yaml
…
│ passed │ Ensure year is plausible                                 │ year           │         │
╰────────┴──────────────────────────────────────────────────────────┴────────────────┴─────────╯
🟢 data contract is valid. Run 15 checks. Took 0.606872 seconds.

Dein Datenprodukt berührt jetzt nur die Felder aus deinem Consumer-driven Contract. Alles andere in orders_v2 darf sich ändern, ohne dich zu brechen. Noch besser: Das Orders-Team kann deinen Kontrakt in seiner CI-Pipeline ausführen und einen Breaking Change abfangen, bevor er live geht. So eine Pipeline baust du in der nächsten Übung.

Kurzer Check
Das Orders-Team will customer_email_address aus orders_v2 entfernen. Bricht das das Datenprodukt SKU Sales?

Bonus

  • Vergleiche den Kontrakt des Produzenten mit dem des Konsumenten: datacontract changelog orders_v2.odcs.yaml orders_v2.consumer_sku_sales.odcs.yaml
  • Lass den Input-Port in sku_sales_per_year.odps.yaml auf orders_v2_consumer_sku_sales zeigen. Sollte der Input-Port auf den Kontrakt des Produzenten verweisen oder auf deinen? Für beides gibt es gute Argumente.