dbt (Data Build Tool) ist eines der populärsten Tools für Datentransformationen. Man hat dabei die Möglichkeit dbt als vollständig gemanagte SaaS-Plattform zu nutzen, wenn man sich für die kostenpflichtige dbt Cloud Version entscheidet. Alternativ kann sich aber auch für dbt Core entschieden werden, um dbt als kostenloses Open Source Tool zu nutzen. dbt Core kann bei der Entwicklung lokal genutzt werden und erfordert lediglich eine Python Installation.
Wenn sich für dbt Core entschieden wurde, muss man im produktiven Betrieb Ressourcen zur Verfügung stellen, auf denen die dbt-Befehle für die Datentransformationen ausgeführt werden können. Auch wenn die Hardwareanforderungen nicht hoch sind, erfordert es zusätzlichen Betriebs- und Wartungsaufwand. Falls nicht schon eine lokale Maschine existiert, muss diese angeschafft und aufgesetzt werden, inklusive Sicherheitsmaßnahmen wie Firewallkonfiguration. Der Betrieb erfordert dann ein Monitoring, um Störungen schnell beheben zu können, sowie regelmäßige Softwareupdates.
Snowflake bietet daher seit einiger Zeit die Möglichkeit dbt Core Projekte nativ in Snowflake selbst zu betreiben. Somit entfällt die Notwendigkeit zusätzlicher Ressourcen. Stattdessen werden die gemanagten Ressourcen von Snowflake genutzt. Wir schauen uns in diesem Artikel anhand eines Beispiels an, welche Schritte notwendig sind, um die Integration zu ermöglichen und wie der Betrieb eines dbt Projekts in Snowflake funktioniert.
Beispielszenario
In der viadee betreiben wir ein Snowflake-DWH, welches Daten aus einem Dorfladen enthält, der Lebensmittel und Produkte des täglichen Bedarfs verkauft. Das Kassensystem des Dorfladens bietet die Möglichkeit auf die Daten per API zuzugreifen. Wie man mit Snowflake Daten aus einer API laden kann, haben wir in einem Anleitungsartikel beschrieben.
Nachdem die Rohdaten aus der API geladen wurden, erfolgt die weitere Verarbeitung über ein dbt Core Projekt, welches wir nativ in Snowflake betreiben. Die Rohdatentabellen aus dem RAW-Schema sind in dbt als Sourcen definiert. Im Staging-Schema werden erste Datenaufbereitungen vorgenommen, während im Core-Schema ein neues Datenmodell mit Dimensionen und Fakten erstellt wird. Basierend darauf werden im Marts-Schema Auswertungen erstellt. Die Historisierung der Daten erfolgt in dbt über Snapshots im Hist-Schema. Die Orchestrierung zum Laden der Daten und der Ausführung des dbt Projekts erfolgt über Azure Data Factory.
Die Architektur ist hier schematisch dargestellt:
Erstellen und Deployen eines dbt Projekts in Snowflake
Um ein dbt Projekt in Snowflake zu betreiben, müssen einige Objekte angelegt werden. Zunächst muss der Code aus dem dbt Core Projekt in Snowflake verfügbar gemacht werden. Dazu kann der Code manuell in eine Stage geladen werden, in Snowsight in einem Workspace eingebunden werden oder über ein Git-Repository synchronisiert werden. Da nur über das Git-Repository eine CI/CD Pipeline realisiert werden kann, empfehlen wir ausdrücklich diese Option. Anschließend müssen ggf. Zugriffe auf dbt-Packages ermöglicht werden und schließlich das dbt Projekt selbst in Snowflake erzeugt werden.
GITHUB_API_INTEGRATION: Für den Zugriff nach außen auf das Repository in GitHub oder GitLab wird eine API-Integration benötigt, welche nur von einem Accountadmin angelegt werden kann.
Git-Repository: Wenn der Zugriff freigegeben ist, kann ein Objekt vom Typ “Git Repository” erstellt werden. Dabei wird ein Klon des Git-Repository erzeugt. Dieser Klon lässt sich mit dem Repository synchronisieren und funktioniert genauso wie ein lokaler Klon zum Entwickeln (s. hier).
Network Rule & External Access Integration für dbt-Packages (optional): Falls weitere dbt-Packages im Projekt genutzt werden, müssen diese über dbt deps installiert werden. Um die Installation in Snowflake zu ermöglichen, wird eine Network Rule benötigt, die den Zugriff auf die URLs zum Download der Packages ermöglicht. Die External Access Integration macht die Network Rule dann für das dbt Projekt verfügbar.
dbt Projekt: Am Ende kann das dbt Projekt selbst in Snowflake als Objekt angelegt werden. Als Quelle wird ein Branch aus dem angelegten Git-Repository verwendet. Das dbt Projekt sollte am besten in einem eigens dafür vorgesehenen Schema angelegt werden.
Für unser Demo-DWH ergeben sich somit folgende SQL-Befehle:
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE API INTEGRATION GITHUB_API_INTEGRATION
API_PROVIDER = git_https_api
API_ALLOWED_PREFIXES = ('https://github.com')
API_USER_AUTHENTICATION = (TYPE = SNOWFLAKE_GITHUB_APP)
ENABLED = TRUE;
CREATE OR REPLACE GIT REPOSITORY DORFLADEN_PROD.DBT.DORFLADEN_GIT_REPO
ORIGIN = 'https://github.com/AndreMachate/dorfladen-demo-dwh'
API_INTEGRATION = GITHUB_API_INTEGRATION;
/* Network Rule für dbt-Packages wie dbt-utils oder codegen */
CREATE OR REPLACE NETWORK RULE SECURITY_DB.NETWORK_RULES.DBT_PACKAGES_RULE
TYPE = HOST_PORT
MODE = EGRESS
VALUE_LIST = ('hub.getdbt.com', 'codeload.github.com');
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION DBT_ACCESS_INTEGRATION
ALLOWED_NETWORK_RULES = (SECURITY_DB.NETWORK_RULES.DBT_PACKAGES_RULE)
ENABLED = TRUE
;
/* Erzeuge dbt Projekt aus dem angelegten GIT-Repository */
CREATE OR REPLACE DBT PROJECT DORFLADEN_PROD.DBT.DORFLADEN_DBT_PROJEKT
FROM '@DORFLADEN_PROD.DBT.DORFLADEN_GIT_REPO/branches/main/dorfladen'
DBT_VERSION='1.10.15'
DEFAULT_TARGET='prod'
EXTERNAL_ACCESS_INTEGRATIONS=(DBT_ACCESS_INTEGRATION);
Wenn sich über das Git-Repository Änderungen am Code ergeben haben, dann muss das dbt Projekt in Snowflake neu deployt werden. dbt Projekte sind in Snowflake selbst versioniert. Bei jedem Deployment werden alle Dateien aus der Quelle kopiert und daraus eine neue Version des Objekts erstellt. Ein Deployment kann über die folgenden SQL-Befehle ausgeführt werden:
-- Aktuellen Code Stand aus dem Repository laden
ALTER GIT REPOSITORY DORFLADEN_PROD.DBT.DORFLADEN_GIT_REPO FETCH;
-- Neue Version des dbt Projekts deployen
ALTER DBT PROJECT DORFLADEN_PROD.DBT.DORFLADEN_DBT_PROJEKT
ADD VERSION
FROM '@DORFLADEN_PROD.DBT.DORFLADEN_GIT_REPO/branches/main/dorfladen';
Ausführung und Orchestrierung von dbt Projekten in Snowflake
Nachdem wir jetzt unser dbt Projekt in Snowflake angelegt und deployt haben, können wir nun auch die Modelle und Tests etc. ausführen. Dafür gibt es den Execute-dbt-Project-Befehl, in dem der dbt-Befehl inklusive Flags als Argument übergeben werden kann:
-- Ausführen aller dbt-Modelle
EXECUTE DBT PROJECT DORFLADEN_PROD.DBT.DORFLADEN_DBT_PROJEKT args='run --target prod';
-- Ausführen der Tests
EXECUTE DBT PROJECT DORFLADEN_PROD.DBT.DORFLADEN_DBT_PROJEKT args='test --target prod';
-- Erstellen der Dokumentation
EXECUTE DBT PROJECT DORFLADEN_PROD.DBT.DORFLADEN_DBT_PROJEKT args='docs generate --target prod';
Die wichtigsten dbt-Befehle für die Ausführung von Projekten werden vom Execute-Befehl unterstützt (s. hier). Auf diese Weise kann nun auch eine automatische Ausführung des dbt Projekts über Tasks in Snowflake selbst definiert werden. Da die Pflege von Snowflake Tasks umständlich ist und es schnell unübersichtlich wird, sobald man einige Tasks miteinander kombiniert, empfiehlt es sich ein externes Orchestrierungstool zu nutzen. In unserem Beispiel haben wir eine Pipeline in Azure Data Factory erstellt, die täglich die Daten aus der API des Kassensystems lädt und in den Rohdatentabellen ablegt. Anschließend wird über EXECUTE DBT PROJECT DORFLADEN_PROD.DBT.DORFLADEN_DBT_PROJEKT args='build --target prod'; ein vollständiger Build des gesamten dbt Projekts in Snowflake durchgeführt.
Überwachen von dbt Projekten über Snowsight
Die Ausführungen der dbt Projekte lassen sich über die Weboberfläche Snowsight analysieren. Dazu im Menü links “Transformations → dbt Projects” auswählen und das Projekt anklicken. Anschließend lässt sich oben der Reiter DAG auswählen und man erhält einen Abhängigkeitsgraphen für die Modelle. Hier lässt sich die Data Lineage analysieren, welche immer mehr an Bedeutung gewinnt. Den genauen Datenfluss und die durchgeführten Transformationen zu kennen macht Auswertungen nachvollziehbar, prüfbar und schafft Vertrauen in die Datenqualität. In dieser Übersicht lässt sich die Data Lineage sogar auf Spaltenebene nachvollziehen und erfüllt somit auch die Anforderungen von Richtlinien wie BCBS 239, welche für einige Banken verpflichtend sind.
Über den Tab “Run History“ können die ausgeführten dbt-Befehle genauer analysiert werden. Klickt man hier auf eine Query, erhält man eine detaillierte Übersicht welche Modelle von der Ausführung betroffen waren, sowie die Konsolenausgabe von dbt. Über den Button rechts lassen sich auch die Build-Artefakte herunterladen. So kann man den gesamten Inhalt aus dem Target-Ordner vom dbt Projekt herunterladen inklusive der Logs und der generierten Dokumentation. Im Target-Ordner befindet sich der kompilierte und ausgeführte Code aller Modelle, Snapshots und Tests. Das hilft insbesondere bei der Fehleranalyse, um nachvollziehen zu können welche Statements fehlschlagen.
CI/CD-Pipeline bauen
dbt unterstützt über die Profile die Trennung von Umgebungen wie Entwicklung, Test und Produktion. Diese Umgebungen können in Snowflake zum Beispiel getrennte Datenbanken sein. Es ist daher sinnvoll, sein dbt Projekt in eine CI/CD Pipeline zu integrieren, um Fehler frühzeitig zu erkennen und einen kontinuierlichen und sicheren Releasezyklus zu gewährleisten. Um den neuesten Codestand in den Klon des Git Repository in Snowflake zu laden und das dbt Projekt neu zu deployen, ist es am einfachsten, die Snowflake CLI zu nutzen. Diese bietet Befehle mit denen man direkt auf dem dbt Projekt in Snowflake agieren kann. Mit GitHub Actions lässt sich dann einfach eine Pipeline bauen, die bei Erstellung eines Pull Requests losläuft, den aktuellen Entwicklungsstand in das dbt Projekt in der Entwicklungsdatenbank deployt und anschließend ein dbt-run und dbt-test ausführt. Wenn die Pipeline erfolgreich gelaufen ist, kann ein Merge stattfinden, sonst müssen bei Fehlern die Entwickler:innen nachbessern. Eine Anleitung für die Konfiguration von GitHub Actions oder GitLab CI/DC in Snowflake ist hier in der offiziellen Dokumentation zu finden. Ein einfaches GitHub Actions Skript für die beschriebene Pipeline würde dann so aussehen:
name: Test deployment
on:
pull_request:
branches:
- master
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install and configure Snowflake CLI
uses: snowflakedb/snowflake-actions@v2.0.4
with:
use-oidc: true
cli-version: "3.16"
- name: Verify connection and deploy
env:
SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
SNOWFLAKE_USER: github_cicd_user
run: |
snow dbt deploy DORFLADEN_DEV.DBT.DORFLADEN_DBT_PROJEKT
--force
--source ./dorfladen
--default-target dev
--external-access-integration DBT_ACCESS_INTEGRATION
--external-access-integration GITHUB_API_INTEGRATION
- name: Execute dbt-run and dbt-test
run: |
snow dbt execute DORFLADEN_DEV.DBT.DORFLADEN_DBT_PROJEKT run
snow dbt execute DORFLADEN_DEV.DBT.DORFLADEN_DBT_PROJEKT test
Analog ließe sich ein Skript für das Continuous-Deployment erstellen, welches ausgeführt wird, sobald ein Merge in den Main Branch erfolgt. Das Skript würde dann entsprechend die Änderungen in der produktiven Umgebung deployen.
Fazit
Wir haben gesehen, dass sich ein dbt Projekt mit wenig Aufwand in Snowflake anlegen und betreiben lässt. Dabei lässt es sich problemlos in bestehende Entwicklungsworkflows integrieren. Der Vorteil des nativen Betriebs in Snowflake ist, dass keine zusätzlichen Ressourcen für die Ausführung von dbt mehr benötigt werden. Insbesondere für kleinere Unternehmen ist dies interessant, da diese ggf. keine eigenen Ressourcen zur Verfügung stellen können oder der Aufwand für den Betrieb und die Wartung zu hoch ist. Stattdessen können die gemanagten Ressourcen von Snowflake verwendet werden und das sogar ohne zusätzliche Kosten. Ein Blick in die Dokumentation zeigt, dass nur die Rechenkosten für die Transformationen anfallen, welche durch dbt ausgelöst werden. Bei einem Betrieb außerhalb von Snowflake würden diese genauso anfallen. Kosten für den eigentlichen dbt-Betrieb entfallen also. Durch die native Integration von dbt in Snowflake lässt sich also ein dbt Core Projekt als SaaS betreiben. Zwar werden dabei nicht alle Funktionen von dbt Cloud unterstützt, jedoch sinkt die Komplexität im Betrieb.
Wenn Sie Interesse haben ein Data Warehouse aufzubauen, ob in Snowflake oder On-Premise, sprechen Sie uns gerne an. Wir bieten auch Schulung in den Themenfeldern Grundlagen von Data Warehousing und Cloud Data Warehouse an.