arrow arrow--cut calendar callback check chevron chevron--large cross cross--large download filter kununu linkedin magnifier mail marker media-audio media-blog media-video menu minus Flieger phone play plus quote share youtube

ELT Pipelines mit dem Data Build Tool

Engineering trifft SQL

„Daten sind das neue Öl“ – dieses und ähnliche Zitate sind bereits seit einigen Jahren in jeder Analytics-Abteilung bekannt. Dass auch Unternehmen diese Devise mittlerweile verinnerlicht haben, erkennt man daran, dass sich heutzutage kaum eines über zu wenige Daten beklagt. Wenn aber die gesammelten Daten zur Analyse und Entscheidungsfindung verwendet werden sollen, stoßen die bisher genutzten Ansätze an ihre Grenzen.

Foto von Maurice Atrops
Maurice Atrops

Data Engineer

Die Probleme beim Betrieb einer modernen Datenplattform, z.B. in Form eines Data Lakes oder eines agilen Data Warehouses, sind vielfältig. Oftmals liegen Daten nur in ihrer Rohform vor und die Data Engineers, die für die Transformation von Rohdaten in auswertbare Daten verantwortlich sind, arbeiten an vielen Themen gleichzeitig. Dies sorgt für Verzögerungen beim Einbinden neuer Datenquellen und als Folge für Frustration bei Analyst*innen oder Dashboard-Developern, die die neugewonnen Daten für Visualisierungen verwenden möchten.

Das Data Build Tool (dbt) hilft diese Probleme zu lösen, indem es z.B. Analyst*innen ermöglicht, selbst die nötigen Transformationen zu implementieren. Dies macht zeitaufwendige Abstimmungen zwischen Data Engineers und Analysts bzgl. Unternehmenslogik obsolet und verkürzt die Time-To-Deliver für neue ETL-Pipelines. Durch den Einsatz von dbt werden die Verantwortlichkeiten für Transformationen in einer Datenplattform klarer getrennt und eine bessere Organisation geschaffen.

Wie dbt funktioniert

Dbt ist ein Framework, das es ermöglicht Transformationen in Datenbanken zu entwickeln. Sein Ziel ist herkömmliches SQL mit Software Engineering Best Practices zu verbinden. Beispiele für diese Best Practices sind die Versionierung mit Git, automatisiertes Testen und Dokumentieren sowie das Anlegen einer Data Lineage.

Abbildung 1: Funktionsweise von dbt
Abbildung 1: Funktionsweise von dbt

Im Kern besteht dbt aus einer Ansammlung von SQL Select Statements (Models). Diese Models werden von dbt genutzt, um Tabellen oder Views anzulegen. Die Reihenfolge, in der die Models ausgeführt werden, wird von dbt automatisch verwaltet und in einem „Directed Acyclic Graph“ (DAG) visualisiert (s. Abb. 2 weiter unten). Jeder Transformationsschritt wird als SQL Select Statement dargestellt, der entweder auf Rohdaten oder auf ein vorangegangenes Model zugreift. So ergibt sich Schritt für Schritt eine Transformationspipeline, die Rohdaten zu nutzbaren Analytics-Daten verarbeitet.

Um einige Schwächen von herkömmlichem SQL auszugleichen, ermöglicht dbt die Benutzung der Templatesprache Jinja innerhalb der Models. Jinja wird zur Laufzeit des Models von dbt mit SQL-Code ersetzt und ermöglicht es auf diese Weise dynamischeren Code zu schreiben. So kann Jinja z.B. für if-else Konstrukte, Schleifen oder Funktionen genutzt werden. Dies erweitert herkömmliches SQL unter anderem um die Fähigkeit je nach Umgebung (Dev, Test, Prod) unterschiedlich viele Daten zu laden oder Funktionen zu definieren, um denselben Code nicht an mehreren Stellen wiederholen zu müssen.

Dbt ermöglicht es Aufgabenbereiche bei der ETL-Entwicklung genauer zu trennen, sowie Business Knowledge früher einzubeziehen. Durch seine leichte Zugänglichkeit via SQL-Code können sich Data Engineers darauf konzentrieren Daten in sogenannten Staging Areas abzulegen und verschiedene Datenquellen anzubinden. Sie stellen daraufhin keinen Bottleneck in der ETL-Entwicklung dar, sondern können die Implementierung der Transformationen an Analyst*innen abgeben. Diese sind durch ihr ausgeprägtes Verständnis für Unternehmensprozesse besser geeignet, um die Rohdaten aus der Staging Area für weitere Analysen vorzubereiten.

Competitor-Vergleich

Wodurch sich dbt auszeichnet

Dbt steht in Konkurrenz mit herkömmlichen ETL-Tools wie Informatica, SSIS oder Talend. Vor allem unterscheidet es sich von diesen Tools im Hinblick auf die Notwendigkeit Code zu schreiben sowie die Wartung und den Betrieb.

Während klassische Tools eine grafische Benutzungsoberfläche bereitstellen, um ETL-Pipelines durch Drag & Drop anzulegen, verzichtet dbt auf eine Oberfläche. Durch diesen Fokus auf die Programmierung mit SQL hat dbt eine niedrigere Einstiegsbarriere. Nutzer*innen, die SQL bereits beherrschen, können ohne zusätzliche Schulungen in die Entwicklung einsteigen. Dies gibt den Developern mehr Freiheiten als ein herkömmliches ETL-Tool, kann allerdings bei Anwender*innen, die kein SQL beherrschen, eine steilere Lernkurve erfordern.

Ein weiterer Unterschied besteht in der Wartung und im Betrieb von dbt. Herkömmliche ETL-Tools richten sich oft an größere Unternehmen und bieten dafür größere Wartungs- und Lizenzverträge an. Dbt ist im Vergleich dazu leichtgewichtiger. Es gibt eine Cloud-Variante, die ein monatliches Bezahlmodell enthält, dafür allerdings dbt als Software-as-a-service anbietet. Falls sich dieses Modell für Kund*innen nicht lohnt, kann dbt selbst gehostet werden. Die notwendigen Python Packages sind Open-Source und können in eine bestehende Infrastruktur, z.B. in Apache Airflow oder Databricks eingebaut werden.

Hands-On

Wie dbt Data Engineering Probleme löst

Um den Einsatz von dbt in einem Data Warehouse zu verproben, haben wir das von den dbt-Developern bereitgestellte „Jaffle-Shop“ Szenario verwendet. Darauf aufbauend haben wir fortgeschrittene Features wie Incremental Models, Snapshots und Tests eingesetzt. Das Ergebnis ist ein Miniatur-Data-Warehouse, das zeigt, wie dbt den Transformationsprozess von Rohdaten zu qualitativ hochwertigen Analytics-Daten unterstützt. Der Code ist öffentlich auf Github zugänglich.

Dbt erzeugt zur besseren Übersicht einen Lineage-Graphen, der anzeigt, wie die einzelnen Transformationen („Models“) voneinander abhängen. Dies sorgt für einen besseren Überblick über das Gesamtprojekt und erklärt, welchen „Weg“ Rohdaten nehmen, bis sie von Datenanalyst*innen oder Dashboards verwendet werden (Stichwort: Data Lineage). In unserem Jaffle-Shop-Beispiel lässt sich anhand des Lineage-Graphen sehr gut die Gesamtstruktur des dbt Projekts visualisieren:

Abbildung 2: Gerichteter azyklischer Graph (DAG) von dbt Models
Abbildung 2: Gerichteter azyklischer Graph (DAG) von dbt Models (zur besseren Lesbarkeit nachgebaut)

Ähnlich zur Medallion-Architektur bei Data Lakes hat unser Data Warehouse verschiedene Ebenen. Jede Ebene steht für ein gewisses Level an Datenqualität. Auf der linken Seite des Schaubilds werden Daten ins Data-Warehouse geladen (Rohdaten). In der nächsten Ebene (Staging) durchlaufen die Rohdaten Transformationen, die die Datenqualität erhöhen, allerdings keine Business-Logik enthalten. Beispiele sind die Konvertierung von Einheiten (z.B. Dollar zu Euro), die Umbenennung von Spalten und einfache Aggregationen als Vorbereitung für komplexere Analysen. Letzteres umfasst z.B. das Gruppieren von Umsätzen je nach Zahlungsart. Die letzte Ebene (Marts) enthält die vollständig transformierten Daten. Diese Tabellen werden von Business Analysts und Dashboarding Tools verwendet, um komplexe Analysen durchzuführen. Als Grundlagen für die Marts dienen die Tabellen aus der Staging Ebene, die in diesem Schritt noch einmal zusammengeführt und durch Business Logik ergänzt werden.

Jede Transformation, die aus Rohdaten qualitativ hochwertige Daten macht, besteht aus einer SQL Select Anfrage. Auf diese Weise steuert dbt den kompletten Workflow in unserem Data-Warehouse. Darüber hinaus gibt es dbt Features, die die Arbeit auf einer modernen Datenplattform vereinfachen und herkömmliches SQL ergänzen.

Testing

Testing ist ein zentraler Baustein im Software Engineering. Während es in herkömmlichem SQL nicht möglich ist Code zu testen, z.B. in Form von Unit Tests, ermöglicht dbt seine Models und deren Funktionsweise zu verifizieren. Tests werden ebenfalls als SQL-Anfragen formuliert. Ein Beispiel aus unserem Data Warehouse Szenario:

SELECT *
FROM {{ ref('stg_payments') }} 
WHERE amount < 0

Dieser Test prüft, ob es Zeilen in unserer 'Payments' Staging Tabelle gibt, deren Rechnungsbetrag kleiner als Null ist. Falls dies der Fall ist, schlägt der Test fehl und wir wissen, dass unsere Annahmen über die Rohdaten nicht korrekt sind.

Incremental Model

Ein weiteres dbt Feature, das die Umsetzung von Data Engineering Best Practices vereinfacht, sind Incremental Models. Diese Models ermöglichen es, dass nicht bei jeder Ausführung die komplette Tabelle transformiert wird, sondern nur die neusten Daten. Dies spart Ausführungszeit und damit auch Kosten. Die Umsetzung geschieht mittels eines Jinja Macros, welches nur aktiviert wird, wenn explizit kein Full-Load durchgeführt werden soll. Dieses Verhalten gestaltet Incremental Models dynamisch und hält die darunterliegenden SQL-Statements schlank.

SELECT
    a.id as analytics_id,
    a.customer_id,
    a.event as website_event,
    a.timestamp as timestamp
FROM {{ source('jaffle_shop', 'raw_analytics') }} a 
{% if is_incremental() %}
    WHERE a.timestamp > (select max(timestamp) from {{ this }})
{% endif %}

Snapshots

Snapshotting ist dbts Lösung, um die Arbeit mit Slowly-Changing-Dimensions (SCDs) zu vereinfachen. Normalerweise müsste ein Data Engineer immer wieder sehr ähnlichen Code schreiben, um die 'valid-from' und 'valid-to' Felder in verschiedene Tabellen zu füllen und upzudaten. Dbt Snapshots konvertieren simple Event-Tabellen, bestehend aus Schlüsselspalten und einem Status, automatisch zu einer SCD-2 Tabelle. In der resultierenden Tabelle werden automatisch 'valid-from' und 'valid-to' Spalten angelegt und im Falle neuer Daten aktualisiert, ohne dass ein Data Engineer denselben Code für unterschiedliche Tabellen schreiben muss. So ist automatisch bekannt, welcher Status z.B. für eine Bestellung in welchem Zeitraum gültig war.

Next-Level ELT Pipelines

Jedoch für große Anwendungsfälle nicht ohne Herausforderungen

Alles in allem ist dbt ein sehr nützliches Tool, um Transformationsschritte in einer modernen Datenplattform zu implementieren. Sein datenbankagnostischer und auf SQL fokussierter Ansatz sorgt dafür, dass es schnell in bestehende Systeme integriert werden kann. Es verkürzt zudem Entwicklungszeiten von ETL-Pipelines, da Analyst*innen früher in den Entwicklungsprozess miteingebunden werden können. Dadurch entsteht kein Bottleneck durch Data Engineers und es ergibt sich eine detailliertere Aufgabentrennung zwischen dem Laden und Extrahieren von Daten und deren Transformation. Dies vermeidet einen Bottleneck durch Data Engineers, die sich auf die Extraktion und das Laden von Daten konzentrieren können. Dennoch muss der Einsatz von dbt gründlich abgewägt werden, da es nicht für jede Datenplattform bei jedem Unternehmen passend ist.

Ein wichtiger Punkt bei dbt ist das Testen und Monitoring von Datenpipelines. dbt bietet einige Features, um dies zu ermöglichen, es gibt jedoch sehr viel weitreichendere Tools, die sich allein mit Monitoring und Data Observability bzw. Lineage beschäftigen. Beispiele sind hier Great Expectations für Data Observability sowie Datadog für Data Lineage. Diese Tools ersetzen dbt nicht, können es aber sinnvoll erweitern.

Ein weiterer Punkt ist der Betrieb von dbt in einer Produktivumgebung. Die Tatsache, dass dbt ein Open Source Projekt ist, macht es für manche Unternehmen schwierig, es in ihre bestehende Datenplattform einzubinden. Die Aufwände für Einbau und Wartung liegen in diesem Fall beim Unternehmen, was es im Vergleich zu herkömmlichen ETL-Tools mit Wartungsverträgen etc. aufwendiger erscheinen lässt.  Vor allem in sehr umfangreichen Datenplattformen empfiehlt es sich daher, dbt in kleineren Use Cases zu verproben.