Skip to main content

#data-engineering

Wenn der dbt-Build durchläuft, die Dashboards aber trotzdem lügen

Ein grüner dbt-Build heißt nicht, dass Ihre Kennzahlen stimmen. So bauen Sie semantische Daten-Gates in dbt und Snowflake — plus ein Layer für Power BI.

Veröffentlicht
2026-06-08
Lesezeit
8 Min.

Kernaussagen

  1. Ein erfolgreicher dbt-Build belegt nur, dass das SQL kompiliert ist und strukturelle Tests gehalten haben — er sagt nichts darüber aus, ob die Zahlen der geschäftlichen Realität entsprechen.
  2. Standard-Pipeline-Tests sind syntaktisch (unique, not_null). Die Fehler, die bis zu den Dashboards durchschlagen, sind semantisch: logischer Drift, verspätete Daten, stille Quelländerungen.
  3. Fangen Sie logischen Drift mit eigenen generischen dbt-Tests und Snowflake-nativen Prüfungen an der Ingestion-Grenze ab, bevor fehlerhafte Ladungen Ihre Modelle erreichen.
  4. Definieren Sie jede Kennzahl genau einmal in einem Semantic Layer und bedienen Sie Power BI aus einem zertifizierten Modell — lokales DAX ist der Ort, an dem aus einem KPI klammheimlich drei werden.

Eine durchgelaufene Daten-Pipeline ist nicht dasselbe wie korrekte Daten. Ein erfolgreicher dbt build garantiert, dass Ihr SQL kompiliert ist, Ihre Tabellen materialisiert wurden und Ihre Primärschlüssel eindeutig und nicht null geblieben sind. Er prüft nicht, ob die Rohdaten der physischen geschäftlichen Realität entsprechen, und tut nichts, um Analysten daran zu hindern, nachgelagert im BI-Tool abweichende, ad-hoc erstellte Kennzahlendefinitionen zu schreiben.

Die kurze Antwort: Standardmäßige Pipeline-Validierung ist syntaktisch, nicht semantisch. Sie prüft Formen und Typen, nicht Bedeutung. Die Abweichungen, die bis auf ein Vorstands-Dashboard durchschlagen — ein Umsatz, der nach Region falsch liegt, eine Auftragssumme, die nicht zu ihren Positionen passt, eine Zahl, die nicht zum CRM passt — rutschen ungehindert durch strukturelle Tests. Um sie abzufangen, brauchen Sie Data-Quality-Gates, die die Zahlen tatsächlich lesen, plus einen einzigen Semantic Layer, damit die Kennzahl genau einmal definiert und überall konsumiert wird.

Warum läuft ein dbt-Build durch, obwohl Geschäftskennzahlen falsch sind?

Wir sehen dasselbe stille Fehlermuster quer durch den DACH-Mittelstand. Sie öffnen das Monitoring-Dashboard: Der Orchestrierungs-DAG ist grün, das Snowflake-Warehouse meldet null Query-Fehler, dbt lief ohne eine einzige Warnung. Und doch meldet Sales Ops, dass die wöchentliche Umsatzzahl in Power BI niedriger ist als das, was das CRM erfasst.

Im technischen Sinne ist nichts kaputt. Genau das ist das Problem. Wenn Ihre Pipeline nur strukturelle Zusicherungen wie unique oder not_null ausführt, klafft ein blinder Fleck zwischen Datenbankerfolg und analytischer Genauigkeit — und genau dort stirbt das Vertrauen.

Same load, two checks

The schema is valid in both columns — only the semantic gate reads the numbers.

OrderΣ itemsHeader totalSyntactic checkSemantic gate
ORD-9081€120.00€120.00PassPass
ORD-9082€45.00€45.00PassPass
ORD-9083€310.00€15.00PassQuarantined
↳ assert_sums_match: Itemized sum is €310.00 but the order header records €15.00.
ORD-9084€85.00€85.00PassPass
A schema test passes every row. Only a relational-integrity gate catches ORD-9083 before it reaches the dashboard.

Jede Zeile oben hat gültige Typen und keine Nullwerte, also meldet ein reiner Schema-Test einen sauberen Durchlauf. Doch ORD-9083 trägt einen Auftragskopf von 15,00 € gegenüber 310,00 € an Positionen. Die Pipeline ist grün; das Dashboard ist falsch.

Architektur eines Data-Quality-Gates in dbt und Snowflake

Um zu verhindern, dass logische Abweichungen Dashboards verfälschen, setzen Sie automatisierte Leitplanken an die Grenzen des Warehouse, statt Rohdaten ungehindert von der Quelle bis zum Semantic Layer fließen zu lassen. Wir nutzen drei Arten von Gate.

Volumetrischer Drift

Verfolgen Sie, ob die täglich eingelesene Datensatzzahl von ihrem gleitenden historischen Durchschnitt abweicht. Eine Quelle, die ihre Ladung still halbiert, wirft selten einen Fehler — sie untertreibt nur leise alles Nachgelagerte.

Relationale Integrität

Stellen Sie sicher, dass Werte über unabhängige Systeme hinweg übereinstimmen — Zahlungs-Gateway-Logs gegen ERP-Aufträge, Positionen gegen Auftragsköpfe —, damit eine Abweichung bei der Ingestion auffällt und nicht erst im Vorstands-Deck.

Semantische Toleranz

Halten Sie nachgelagerte Modell-Refreshes an, wenn eine Kernkennzahl aus einem definierten historischen Band driftet. Das Gate schlägt laut fehl, damit ein Mensch hinschaut, bevor die Zahl ausgeliefert wird.

Einen fortgeschrittenen semantischen Test in dbt bauen

Hier ist eine konkrete Umsetzung: ein eigener generischer Test, der die relationale Integrität über zwei Modelle hinweg prüft — er validiert, dass die Summe der Positionsbeträge dem Transaktionskopf entspricht, innerhalb einer Toleranz.

Legen Sie den Test unter tests/generic/assert_sums_match.sql an. Ein generischer Test gibt die fehlschlagenden Zeilen zurück, der Test schlägt also fehl, sobald die Query irgendetwas liefert:

{% test assert_sums_match(model, column_name, compare_model, compare_column, group_by_column, tolerance=0.01) %}

with source_totals as (
    select
        {{ group_by_column }} as join_key,
        sum({{ column_name }}) as primary_sum
    from {{ model }}
    group by 1
),

compare_totals as (
    select
        {{ group_by_column }} as join_key,
        sum({{ compare_column }}) as reference_sum
    from {{ compare_model }}
    group by 1
),

discrepancies as (
    select
        s.join_key,
        s.primary_sum,
        c.reference_sum,
        abs(s.primary_sum - c.reference_sum) as absolute_difference
    from source_totals s
    join compare_totals c on s.join_key = c.join_key
    where abs(s.primary_sum - c.reference_sum) > {{ tolerance }}
)

select * from discrepancies

{% endtest %}

Referenzieren Sie ihn anschließend in models/schema.yml, damit er bei jedem Deployment läuft. Versehen Sie ihn mit einem Tag, damit Sie in der CI gezielt nur die Gates auswählen können:

version: 2

models:
  - name: fct_order_items
    description: "Granular line items for customer orders."
    columns:
      - name: line_item_amount_eur
        description: "Net amount of the individual line."
        tests:
          - assert_sums_match:
              compare_model: ref('fct_orders')
              compare_column: total_order_amount_eur
              group_by_column: order_id
              tolerance: 0.05
              tags: ['dq_gate']

Quarantäne an der Ingestion-Schicht mit Snowflake

Jede semantische Prüfung innerhalb von dbt auszuführen bedeutet, dass anomale Zeilen bereits in Ihren modellierten Tabellen gelandet sind. Schieben Sie für Quellen mit hohem Volumen die günstigsten Gates vor, indem Sie Snowflake Streams und Tasks nutzen: Ein Stream verfolgt neue Zeilen auf der rohen Landing-Tabelle, ein geplanter Task wertet die Integritätsregel aus, und fehlschlagende Batches werden in eine Quarantäne-Tabelle umgeleitet, statt weiterzufließen. Sie verbrauchen weniger Warehouse-Compute für das erneute Verarbeiten fehlerhafter Ladungen, und dbt sieht nur jemals Daten, die das erste Gate bereits passiert haben.

Den Kreis schließen: ein Semantic Layer für Power BI

Selbst mit sauberen Daten in Snowflake driften Kennzahlen in dem Moment, in dem Analysten ihre eigenen KPIs lokal in Power BI mit eigenem DAX berechnen. Aus einem „Umsatz“-Measure werden klammheimlich drei, jedes subtil anders, und niemand kann sagen, welches richtig ist. Saubere Warehouse-Daten sind notwendig, aber nicht hinreichend — die Definition muss ebenfalls zentralisiert sein.

Die Kennzahl genau einmal mit dem dbt Semantic Layer definieren

Mit dem dbt Semantic Layer deklarieren Sie jedes Measure genau einmal, im Code-Repository, und jeder Konsument liest dieselbe Definition:

semantic_models:
  - name: revenue_performance
    model: ref('fct_orders')
    dimensions:
      - name: order_date
        type: time
        type_params:
          time_granularity: day
    measures:
      - name: total_revenue
        agg: sum
        expr: total_order_amount_eur

metrics:
  - name: sales_revenue
    label: "Sales Revenue (EUR)"
    type: simple
    type_params:
      measure: total_revenue

Power BI aus einem zertifizierten Modell bedienen, nicht aus Rohtabellen

Um diese zentralisierte Logik mit Power BI zu verbinden, ohne sie neu zu implementieren:

  1. 01

    Den XMLA-Endpunkt aktivieren

    Schalten Sie in einem Power-BI-Premium- oder Fabric-Workspace XMLA Read/Write ein, damit externe Tools Semantikmodelle programmatisch bereitstellen und verwalten können statt per Point-and-Click.

  2. 02

    Aus einem zertifizierten Semantikmodell berichten

    Bauen Sie Berichte gegen ein einziges, zertifiziertes Power-BI-Semantikmodell, statt rohe Datenbanktabellen in jeden Bericht zu importieren. Eine Definition, viele Berichte — keine DAX-Abspaltungen pro Bericht.

  3. 03

    Definitionen mit TMDL in Git versionieren

    Stellen Sie das semantische Schema als Code mit der Tabular Model Definition Language (TMDL) bereit und verfolgen Sie es, bearbeitet mit dem Tabular Editor. Kennzahlenänderungen laufen dann vor der Produktion durch Peer-Review und automatisierte Tests — derselbe Workflow wie im Rest Ihres Engineerings.

Sobald Kennzahlenlogik in Git-verwalteten Modellen lebt, ist eine Änderung am „Umsatz“ ein Pull Request und keine stille Bearbeitung in jemandes lokalem Bericht.

Alerting: schlechte Daten abfangen, bevor es ein Stakeholder tut

Das letzte Stück ist proaktives Alerting. Wenn ein semantisches Gate fehlschlägt, sollte die Benachrichtigung den Data Engineer in Rufbereitschaft erreichen — und nicht darauf warten, dass eine Führungskraft ein kaputtes Diagramm bemerkt. Verdrahten Sie die Gate-Auswahl in der CI, sodass ein Fehlschlag den Alert-Pfad auslöst:

# In the CI pipeline
dbt build --select tag:dq_gate || python scripts/alert_data_team.py --status failure

Das Alert-Skript meldet den genauen Fehler, sodass derjenige, der ihn übernimmt, bereits weiß, was kaputtgegangen ist:

import os
import requests

def send_teams_alert(failed_test_name, affected_rows):
    webhook_url = os.environ["TEAMS_WEBHOOK_URL"]
    payload = {
        "title": "🚨 Data quality gate failure",
        "text": (
            f"Semantic validation **{failed_test_name}** failed on Snowflake. "
            f"Found **{affected_rows}** mismatched records. Downstream refreshes halted."
        ),
    }
    requests.post(webhook_url, json=payload, timeout=10)

Vertrauen in die Zahlen wiederherstellen

Wenn ein Unternehmen den Glauben an seine Analytik verliert, ist das Fehlermuster vorhersehbar: Teams kehren zu manuellen Tabellenkalkulationen zurück, Datensilos bilden sich neu, und die strategische Ausrichtung erodiert leise. Diese Lücke zu schließen heißt, über reine Syntaxvalidierung hinauszugehen — hin zu automatisierten semantischen Gates und einer einzigen, governten Kennzahlenschicht. Es ist dieselbe operative Disziplin, die darüber entscheidet, ob ein KI-Pilot je in Produktion geht — das Modell ist, wie der grüne Build, selten der Ort, an dem das Projekt tatsächlich scheitert.

Wir entwerfen und implementieren Cloud-Data-Warehouses, Pipeline-Automatisierung und BI-Architekturen für Unternehmen im DACH-Mittelstand — mit von Anfang an eingebauten Data-Quality-Gates und Semantic Layern, nicht erst nachträglich angeschraubt nach dem ersten falschen Vorstands-Deck.

// QUELLEN

  1. Add data tests to your DAG — dbt Labs, 2025
  2. About MetricFlow and the dbt Semantic Layer — dbt Labs, 2025
  3. Introduction to Streams — Snowflake, 2025
  4. Semantic model connectivity with the XMLA endpoint — Microsoft, 2026
  5. Tabular Model Definition Language (TMDL) overview — Microsoft, 2025

Häufige Fragen

  • Warum läuft ein dbt-Build durch, obwohl die Geschäftskennzahlen falsch sind?
    Ein erfolgreicher dbt-Build garantiert nur, dass Ihr SQL kompiliert ist, Tabellen materialisiert wurden und strukturelle Tests (unique, not_null, relationships) gehalten haben. Er prüft nicht, ob die Werte der physischen geschäftlichen Realität entsprechen, und hindert Analysten nicht daran, abweichende Kennzahlendefinitionen nachgelagert im BI-Tool zu schreiben. Das sind semantische Fehler, und Standard-Pipeline-Tests sind syntaktisch.
  • Was ist ein Data-Quality-Gate?
    Ein Data-Quality-Gate ist eine automatisierte Prüfung an einer Grenze in Ihrem Warehouse — typischerweise bei der Ingestion oder vor der Veröffentlichung —, die Daten anhält oder in Quarantäne stellt, wenn sie gegen eine logische und nicht nur strukturelle Regel verstoßen. Beispiele: ein Tagesvolumen, das von seinem gleitenden Durchschnitt abweicht, Transaktionssummen, die zwischen zwei Quellsystemen nicht übereinstimmen, oder eine Kernkennzahl, die aus der historischen Toleranz driftet.
  • Wie schreibt man einen semantischen Test in dbt?
    Verwenden Sie einen eigenen generischen Test: ein parametrisiertes SQL-Macro in tests/generic/, das Zeilen zurückgibt, die Fehler repräsentieren. Für relationale Integrität verknüpfen Sie zwei Modelle über einen Schlüssel, vergleichen aggregierte Werte und geben jedes Paar zurück, dessen absolute Differenz eine Toleranz überschreitet. Den Test hängen Sie dann an eine Spalte in der schema.yml, damit er bei jedem Build läuft.
  • Wie stoppt man Kennzahlen-Drift in Power BI?
    Definieren Sie jedes Measure genau einmal in einem zentralen Semantic Layer (dem dbt Semantic Layer oder einem einzigen zertifizierten Power-BI-Semantikmodell) und lassen Sie alle Berichte darauf zugreifen, statt KPIs in lokalem DAX neu zu berechnen. Verwalten Sie diese Definitionen per TMDL in Git, damit Änderungen vor der Produktion durch Review und Tests laufen.

Was this helpful?

// share

linkedin email

diesen Beitrag im Postfach?

Eine kurze Notiz pro Monat — nur wenn es etwas zu lesen gibt.

 per-rss-abonnieren

// oder schreib uns: hello@saloid.com · gräfelfing · de