In dbt werden Tests normalerweise erst nach dem Schreiben der Daten ausgeführt. Doch was wäre, wenn wir die Qualität bereits während des Builds sicherstellen? Erfahre, wie du mit einer benutzerdefinierten Materialization Tests vor dem Schreiben durchführst.

Einleitung

Datenqualität ist ein entscheidender Faktor für verlässliche Analysen und reibungslose Datenpipelines. Doch wann sollte eine Tabelle in eine Data Platform geschrieben werden? Reicht es, wenn ein Test erfolgreich ist, oder müssen alle Tests bestehen?

In dbt ist der Standardprozess Run & Test: Modelle werden erst geschrieben und dann getestet. Doch was passiert, wenn nach dem Schreiben ein Test fehlschlägt? Dann könnten fehlerhafte Daten in der Plattform landen.

In diesem Beitrag zeigen wir, wie man bereits während des dbt build sicherstellt, dass Datenqualität gewährleistet ist – durch eine eigene Custom Materialization.

Das Problem: Tests nach dem Schreiben

Stellen wir uns eine Mapping-Tabelle zwischen Produkt und Produktgruppe vor. Die eindeutige Kennung ist product_id.

Ausgangsdaten

Die Rohdaten enthalten folgende Einträge:

PRODUCT_ID PRODUCT_DESCRIPTION PRODUCT_GROUP
p001 Produkt_A pg001
p002 Produkt_B pg001
p003 Produkt_C pg002

Mit dbt run --select stg_product erstellen wir eine Staging-Tabelle.
Um sicherzustellen, dass product_id einzigartig ist, definieren wir in schema.yml folgenden Test:


version: 2

models:
  - name: stg_product
    description: raw data for product mapping.
    columns:
      - name: product_id
        data_tests:
          - unique

Ein dbt test bestätigt, dass der Test bestanden wird. Perfekt!

Doch was passiert, wenn sich die Datenbasis ändert?

Ein unerwarteter Fehler

Ein Mitarbeiter im Materialmanagement ändert in der Quelle die Zuordnung von p001 zu einer neuen Produktgruppe pg003, ohne die alte Zuordnung zu entfernen:

PRODUCT_ID PRODUCT_DESCRIPTION PRODUCT_GROUP
p001 Produkt_A pg001
p002 Produkt_B pg001
p003 Produkt_C pg002
p003 Produkt_C pg002

Nun wird unser Staging-Modell erstellt und getestet. Das Ergebnis?

  • Die Tabelle wird geschrieben
  • Der Test schlägt fehl

Das Problem: Die Tabelle mit dem fehlerhaften Eintrag bleibt in der Data Platform erhalten!

Dies kann zu inkonsistenten Analysen und fehlerhaften Berechnungen führen.

Die Lösung: Tests vor dem Schreiben ausführen

Statt Tests erst nach dem Schreiben auszuführen, wollen wir sicherstellen, dass die Daten nur dann geschrieben werden, wenn alle Tests erfolgreich sind.

Custom Materialization in dbt

Die Lösung ist eine eigene Materialization. Diese prüft, ob der Test erfolgreich ist, bevor die Daten in das Zielschema geschrieben werden.


{% materialization tested_table, adapter='default', supported_languages=['sql', 'python'] %}

  […]

  {% if test_results|length > 0 %}

    {% do log("Test fehlgeschlagen: Eindeutigkeit von " ~ unique_key , info=True) %}
    {% do log(test_results.print_table() , info=True) %}

    {% set target_relation = old_relation %}  -- Die alte Tabelle bleibt erhalten

  {% else %}

    {% do log("Test bestanden " ~ unique_key , info=True) %}
    {% set target_relation = api.Relation.create(identifier=identifier, schema=schema, database=database, type='table') %}

    {% if old_relation is not none %}

      {% if old_relation.is_view %}
        {% do adapter.drop_relation(old_relation) %}
      {% else %}
        {% do adapter.rename_relation(old_relation, backup_relation) %}
      {% endif %}

    {% endif %}

  {{ adapter.rename_relation(intermediate_relation, target_relation) }}

  {% do create_indexes(target_relation) %}

  {% endif %}

  […]

{% endmaterialization %}

Mit dieser Anpassung gilt:

✅ Falls der Test besteht, wird die neue Tabelle geschrieben.
❌ Falls der Test fehlschlägt, bleibt die alte Version erhalten.

So wird sichergestellt, dass nur qualitativ einwandfreie Daten in die Data Platform gelangen.

Unterschied zwischen Tests beim Build und regulären Tests

Nicht jeder Test muss vor dem Schreiben erfolgen. Manche Tests können weiterhin erst nach dem Schreiben ausgeführt werden.

Dafür erweitern wir unser schema.yml um eine neue Eigenschaft pre_tests:

version: 2

models:
  - name: stg_product
    description: raw data for product mapping.
    columns:
      - name: product_id
        pre_tests:
          - unique
        data_tests:
          - unique
          - not_null

Damit können wir vorab festlegen, welche Tests zwingend bestanden werden müssen, bevor Daten geschrieben werden.

Unsere Materialization nutzt diese Information folgendermaßen:

{% set column_definition = model["columns"] %}
{% set pre_tests = column_definition[unique_key]["pre_tests"] %}
{% do log("Pre-Tests: " ~ pre_tests , info=True) %}

So bleibt unsere Pipeline flexibel und performant.

Fazit: Mehr Datenqualität durch vorausschauendes Testen

Mit dieser Methode verhindern wir, dass fehlerhafte Daten in unser Data Warehouse gelangen.

Vorteile dieser Lösung:

✔️ Daten werden nur geschrieben, wenn alle definierten Pre-Tests bestehen
✔️ Fehlerhafte Tabellen bleiben unberührt – nachgelagerte Produkte funktionieren bis der Fehler behoben ist
✔️ Flexibel konfigurierbar: Unterschied zwischen Pre-Tests und regulären Tests

💡 Empfehlung: Ergänze zusätzliche Freshness-Checks, um sicherzustellen, dass nachgelagerte Modelle richtig behandelt werden.

FAQ

1. Warum ist es problematisch, Tests erst nach dem Schreiben auszuführen?

Weil fehlerhafte Daten bereits in die Data Platform gelangen können, bevor der Fehler entdeckt wird und davon insbesondere Output Ports betroffen sein können die in Dashboards verwendet werden.

2. Ist es kompliziert, eine eigene Materialization in dbt zu erstellen?

Nein! Der dbt core Code ist komplett offen für Materializations. Unsere Lösung basiert auf einfachen Anpassungen.

3. Was passiert, wenn ein Test fehlschlägt?

Die bestehende Tabelle bleibt bestehen, die neue (fehlerhafte) Version wird nicht übernommen.

4. Welche Tests sollten vor dem Schreiben ausgeführt werden?

Tests, die die Integrität der Daten sicherstellen, z. B. unique, not_null oder foreign_key.

5. Bleibt dbt trotzdem performant?

Ja! Die Tests werden nur für die neue Tabelle ausgeführt, bevor sie übernommen wird.

Du willst mehr zu dbt erfahren?

Melde dich einfach unverbindlich bei uns. Wir besprechen deinen Use Case und wie du in deinem Unternehmen von dbt profitieren kannst.

Jetzt anfragen

Die neuesten Blogbeiträge

Entdecken Sie unsere neuesten Blog-Beiträge

Basics für dbt test - Teil 1

Wie dbt Test euren Alltag und den eurer Berichtsempfänger erleichtert - Teil 1
Mehr erfahren

Basics für dbt test - Teil 2

Wie dbt Test euren Alltag und den eurer Berichtsempfänger erleichtert - Teil 2
Mehr erfahren

Was ist dbt?

Eine kurze Einführung in das beliebte Data Transformation Framework
Mehr erfahren
Zur Übersicht

Unsere Lösungen machen Ihr Leben einfacher und effizienter

Erfahre mehr über unser Unternehmen und wie wir dir helfen können.