Die manuelle Erstellung von dbt-Modellen ist ein mühsamer Prozess, der Stunden an Arbeitszeit verschlingt. Besonders wenn keine (größeren) Geschäftstransformationen vorgenommen werden, gehört diese Aufgabe nicht zu den attraktivsten Tätigkeiten eines Dateningenieurs.
Aber was wäre, wenn du diesen gesamten Prozess automatisieren könntest? In dieser Anleitung zeige ich dir genau, wie GitLab Duo Agent Platform umfassende dbt-Modelle in nur wenigen Minuten generiert – komplett mit ordnungsgemäßer Struktur, Tests und Dokumentation.
Was wir aufbauen
Unser Marketing-Team möchte Werbeinvestitionen effektiv verwalten und optimieren. Eine der Werbeplattformen ist Reddit, daher extrahieren wir Daten von der Reddit Ads API in unsere unternehmensweite Datenplattform Snowflake. Bei GitLab haben wir drei Speicherebenen:
-
raw
-Ebene – erster Landepunkt für unverarbeitete Daten aus externen Quellen; noch nicht für geschäftliche Nutzung bereit -
prep
-Ebene – erste Transformationsebene mit Quellmodellen; noch nicht für allgemeine geschäftliche Nutzung bereit -
prod
-Ebene – final transformierte Daten, bereit für geschäftliche Nutzung und Tableau-Berichte
Für diese Anleitung sind die Daten bereits durch unsere Extraktionslösung Fivetran in der raw-Ebene gelandet, und wir werden dbt-Modelle generieren, die die Daten von der prep
-Ebene zur prod
-Ebene verarbeiten.
Ohne eine einzige Zeile dbt-Code selbst schreiben zu müssen, werden wir am Ende der Anleitung Folgendes haben:
-
Quellmodelle in der prep-Ebene
-
Workspace-Modelle in der prod-Ebene
-
Vollständige dbt-Konfigurationen für alle 13 Tabellen (einschließlich 112 Spalten) im Reddit Ads-Datensatz
-
Test-Abfragen zur Validierung der Ergebnisse
Der gesamte Prozess dauert weniger als 10 Minuten – im Vergleich zu den Stunden, die normalerweise dafür benötigt würden. Hier sind die zu befolgenden Schritte:
1. Die Datenstruktur vorbereiten
Bevor GitLab Duo unsere Modelle generieren kann, muss es die vollständige Tabellenstruktur verstehen. Der Schlüssel liegt darin, eine Abfrage gegen Snowflakes Informationsschema auszuführen, da wir derzeit untersuchen, wie wir GitLab Duo über das Model Context Protocol (MCP) mit unserer Snowflake-Instanz verbinden können:
SELECT
table_name,
column_name,
data_type,
is_nullable,
CASE
WHEN is_nullable = 'NO' THEN 'PRIMARY_KEY'
ELSE NULL
END as key_type
FROM raw.information_schema.columns
WHERE table_schema = 'REDDIT_ADS'
ORDER BY table_name, ordinal_position;
Diese Abfrage erfasst:
-
Alle Tabellen- und Spaltennamen
-
Datentypen für die korrekte Modellstruktur
-
Nullable-Einschränkungen
-
Primärschlüssel-Identifikation (nicht-nullable Spalten in diesem Datensatz)
Profi-Tipp: Im Reddit Ads-Datensatz dienen alle nicht-nullable Spalten als Primärschlüssel – ein Muster. Ich habe dies überprüft, indem ich Tabellen wie ad_group
kontrollierte, die zwei nicht-nullable Spalten (account_id
und id
) hat, die beide als Primärschlüssel markiert sind. Die Ausführung dieser Abfrage lieferte 112 Zeilen Metadaten, die ich als CSV-Datei für die Modellgenerierung exportierte. Während dieser manuelle Schritt heute gut funktioniert, untersuchen wir eine direkte Integration von GitLab Duo mit unserer Datenplattform über MCP, um diesen Prozess vollständig zu automatisieren.
2. GitLab Duo einrichten
Es gibt zwei Möglichkeiten, mit GitLab Duo zu interagieren:
-
Web-UI-Chat-Funktion
-
Visual Studio Code-Plugin
Ich habe mich für das VS Code-Plugin entschieden, da ich die dbt-Modelle lokal ausführen kann, um sie zu testen.
3. Den 'magischen' Prompt eingeben
Hier ist der exakte Prompt, den ich zur Generierung des gesamten dbt-Codes verwendet habe:
Create dbt models for all the tables in the file structure.csv.
I want to have the source models created, with a filter that dedupes the data based on the primary key. Create these in a new folder reddit_ads.
I want to have workspace models created and store these in the workspace_marketing schema.
Take this MR as example: [I've referenced to previous source implementation]. Here is the same done for Source A, but now it needs to be done for Reddit Ads.
Please check the dbt style guide when creating the code: https://handbook.gitlab.com/handbook/enterprise-data/platform/dbt-guide/
Schlüsselelemente, die diesen Prompt effektiv machten:
-
Klare Spezifikationen für sowohl Quell- als auch Workspace-Modelle
-
Referenzbeispiel aus einem vorherigen ähnlichen Merge Request
-
Style Guide-Referenz zur Sicherstellung von Codequalität und Konsistenz
-
Spezifisches Schema-Targeting für ordnungsgemäße Organisation
4. GitLab Duos Prozess
Nach dem Einreichen des Prompts machte sich GitLab Duo an die Arbeit. Der gesamte Generierungsprozess dauerte einige Minuten, während dessen GitLab Duo:
-
Die CSV-Eingabedatei las und analysierte
-
Tabellenstrukturen aus den Metadaten untersuchte
-
Unseren dbt-Style-Guide als Referenz für Coding-Standards nutzte
-
Ähnliche Merge Requests berücksichtigte für die korrekte Strukturierung
-
Quellmodelle für alle 13 Tabellen generierte
-
Workspace-Modelle für alle 13 Tabellen erstellte
-
Unterstützende dbt-Dateien generierte:
sources.yml
-Konfigurationschema.yml
-Dateien mit Tests und Dokumentation- Aktualisierte
dbt_project.yml
mit Schema-Referenzen
Die Ergebnisse
Die Ausgabe war bemerkenswert:
-
1 modifizierte Datei: dbt_project.yml (reddit_ads Schema-Konfiguration hinzugefügt)
-
29 neue Dateien:
- 26 dbt-Modelle (13 Quell- + 13 Workspace-Modelle)
- 3 YAML-Dateien
-
Fast 900 Zeilen Code automatisch generiert
-
Integrierte Daten-Tests, einschließlich Unique-Constraints auf Primärschlüssel-Spalten
-
Generische Beschreibungen für alle Modelle und Spalten
-
Saubere Deduplizierungs-Logik in Quellmodellen
-
Saubere, konsistente Code-Struktur gemäß dem GitLab dbt-Style-Guide
transform/snowflake-dbt/
├── dbt_project.yml [MODIFIZIERT]
└── models/
├── sources/
│ └── reddit_ads/
│ ├── reddit_ads_ad_group_source.sql [NEU]
│ ├── reddit_ads_ad_source.sql [NEU]
│ ├── reddit_ads_business_account_source.sql [NEU]
│ ├── reddit_ads_campaign_source.sql [NEU]
│ ├── reddit_ads_custom_audience_history_source.sql [NEU]
│ ├── reddit_ads_geolocation_source.sql [NEU]
│ ├── reddit_ads_interest_source.sql [NEU]
│ ├── reddit_ads_targeting_community_source.sql [NEU]
│ ├── reddit_ads_targeting_custom_audience_source.sql [NEU]
│ ├── reddit_ads_targeting_device_source.sql [NEU]
│ ├── reddit_ads_targeting_geolocation_source.sql [NEU]
│ ├── reddit_ads_targeting_interest_source.sql [NEU]
│ ├── reddit_ads_time_zone_source.sql [NEU]
│ ├── schema.yml [NEU]
│ └── sources.yml [NEU]
└── workspaces/
└── workspace_marketing/
└── reddit_ads/
├── schema.yml [NEU]
├── wk_reddit_ads_ad.sql [NEU]
├── wk_reddit_ads_ad_group.sql [NEU]
├── wk_reddit_ads_business_account.sql [NEU]
├── wk_reddit_ads_campaign.sql [NEU]
├── wk_reddit_ads_custom_audience_history.sql [NEU]
├── wk_reddit_ads_geolocation.sql [NEU]
├── wk_reddit_ads_interest.sql [NEU]
├── wk_reddit_ads_targeting_community.sql [NEU]
├── wk_reddit_ads_targeting_custom_audience.sql [NEU]
├── wk_reddit_ads_targeting_device.sql [NEU]
├── wk_reddit_ads_targeting_geolocation.sql [NEU]
├── wk_reddit_ads_targeting_interest.sql [NEU]
└── wk_reddit_ads_time_zone.sql [NEU]
Beispiel des generierten Codes
Hier ist ein Beispiel für die Qualität des generierten Codes. Für die time_zone
-Tabelle erstellte GitLab Duo:
Prep-Ebene Quellmodell
WITH source AS (
SELECT *
FROM {{ source('reddit_ads','time_zone') }}
QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY _fivetran_synced DESC) = 1
),
renamed AS (
SELECT
id::VARCHAR AS time_zone_id,
code::VARCHAR AS time_zone_code,
dst_offset::NUMBER AS time_zone_dst_offset,
is_dst_active::BOOLEAN AS is_time_zone_dst_active,
name::VARCHAR AS time_zone_name,
offset::NUMBER AS time_zone_offset,
_fivetran_synced::TIMESTAMP AS fivetran_synced_at
FROM source
)
SELECT * FROM renamed
Schema.yml
models:
- name: reddit_ads_time_zone_source
description: Zeitzonendaten aus dem Reddit Ads-System
columns:
- name: time_zone_id
description: Eindeutige Kennung für Zeitzoneneinträge
data_tests:
- unique
- not_null
- name: time_zone_code
description: Code für die Zeitzone
- name: time_zone_dst_offset
description: Sommerzeitverschiebung für die Zeitzone
- name: is_time_zone_dst_active
description: Flag, das angibt, ob Sommerzeit aktiv ist
- name: time_zone_name
description: Name der Zeitzone
- name: time_zone_offset
description: Verschiebung für die Zeitzone
- name: fivetran_synced_at
description: Zeitstempel, wann der Datensatz zuletzt von Fivetran synchronisiert wurde
Source.yml
sources:
- name: reddit_ads
database: RAW
schema: reddit_ads
loaded_at_field: _fivetran_synced
loader: fivetran
description: Reddit Ads-Daten
quoting:
database: true
schema: false
identifier: false
tables:
- name: time_zone
Workspace-Modell
WITH source AS (
SELECT *
FROM {{ ref('reddit_ads_time_zone_source') }}
)
SELECT * FROM source
5. Qualitätsvalidierung
Nachdem der Code gut aussah, habe ich ihn zum MR gepusht und die CI-Test-Pipeline ausgeführt, um den Code zu testen und das Ergebnis zu validieren. Ich bat GitLab Duo, eine Validierungsabfrage zu erstellen:
Create a test query to test the row counts between the raw layer and the workspace layer. Keep in mind that we do deduplication, so we can compare both using distinct on the primary keys.
Die KI generierte eine umfassende Validierungsabfrage, die:
-
Zeilenanzahlen zwischen raw- und workspace-Ebenen verglich
-
Die Deduplizierungs-Logik berücksichtigte
-
Alle 13 Tabellen testete
-
Datenerhaltungsprozentsätze berechnete
Generierte SQL-Test-Abfrage
-- Reddit Ads Zeilenanzahl-Validierungstest
-- Vergleicht eindeutige Zählungen zwischen RAW-Ebene und WORKSPACE_MARKETING-Ebene
-- Berücksichtigt Deduplizierungs-Logik in Quellmodellen
WITH raw_counts AS (
-- Tabellen mit einzelnem Primärschlüssel
SELECT 'ad' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.AD
UNION ALL
SELECT 'business_account' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.BUSINESS_ACCOUNT
UNION ALL
SELECT 'campaign' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.CAMPAIGN
UNION ALL
SELECT 'custom_audience_history' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.CUSTOM_AUDIENCE_HISTORY
UNION ALL
SELECT 'geolocation' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.GEOLOCATION
UNION ALL
SELECT 'interest' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.INTEREST
UNION ALL
SELECT 'time_zone' AS table_name, COUNT(DISTINCT id) AS raw_count
FROM RAW.REDDIT_ADS.TIME_ZONE
-- Tabellen mit zusammengesetzten Primärschlüsseln
UNION ALL
SELECT 'ad_group' AS table_name, COUNT(DISTINCT CONCAT(account_id, '|', id)) AS raw_count
FROM RAW.REDDIT_ADS.AD_GROUP
UNION ALL
SELECT 'targeting_community' AS table_name, COUNT(DISTINCT CONCAT(ad_group_id, '|', community_id)) AS raw_count
FROM RAW.REDDIT_ADS.TARGETING_COMMUNITY
UNION ALL
SELECT 'targeting_custom_audience' AS table_name, COUNT(DISTINCT CONCAT(ad_group_id, '|', custom_audience_id)) AS raw_count
FROM RAW.REDDIT_ADS.TARGETING_CUSTOM_AUDIENCE
UNION ALL
SELECT 'targeting_device' AS table_name, COUNT(DISTINCT _fivetran_id) AS raw_count
FROM RAW.REDDIT_ADS.TARGETING_DEVICE
UNION ALL
SELECT 'targeting_geolocation' AS table_name, COUNT(DISTINCT CONCAT(ad_group_id, '|', geolocation_id)) AS raw_count
FROM RAW.REDDIT_ADS.TARGETING_GEOLOCATION
UNION ALL
SELECT 'targeting_interest' AS table_name, COUNT(DISTINCT CONCAT(ad_group_id, '|', interest_id)) AS raw_count
FROM RAW.REDDIT_ADS.TARGETING_INTEREST
),
workspace_counts AS (
-- Workspace-Ebene zählt unter Verwendung von Primärschlüsseln aus schema.yml
SELECT 'ad' AS table_name, COUNT(DISTINCT ad_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_AD
UNION ALL
SELECT 'business_account' AS table_name, COUNT(DISTINCT business_account_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_BUSINESS_ACCOUNT
UNION ALL
SELECT 'campaign' AS table_name, COUNT(DISTINCT campaign_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_CAMPAIGN
UNION ALL
SELECT 'custom_audience_history' AS table_name, COUNT(DISTINCT custom_audience_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_CUSTOM_AUDIENCE_HISTORY
UNION ALL
SELECT 'geolocation' AS table_name, COUNT(DISTINCT geolocation_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_GEOLOCATION
UNION ALL
SELECT 'interest' AS table_name, COUNT(DISTINCT interest_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_INTEREST
UNION ALL
SELECT 'time_zone' AS table_name, COUNT(DISTINCT time_zone_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_TIME_ZONE
-- Tabellen mit zusammengesetzten Primärschlüsseln
UNION ALL
SELECT 'ad_group' AS table_name, COUNT(DISTINCT CONCAT(ad_group_account_id, '|', ad_group_id)) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_AD_GROUP
UNION ALL
SELECT 'targeting_community' AS table_name, COUNT(DISTINCT CONCAT(targeting_community_ad_group_id, '|', targeting_community_id)) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_TARGETING_COMMUNITY
UNION ALL
SELECT 'targeting_custom_audience' AS table_name, COUNT(DISTINCT CONCAT(targeting_custom_audience_ad_group_id, '|', targeting_custom_audience_id)) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_TARGETING_CUSTOM_AUDIENCE
UNION ALL
SELECT 'targeting_device' AS table_name, COUNT(DISTINCT targeting_device_fivetran_id) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_TARGETING_DEVICE
UNION ALL
SELECT 'targeting_geolocation' AS table_name, COUNT(DISTINCT CONCAT(targeting_geolocation_ad_group_id, '|', targeting_geolocation_id)) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_TARGETING_GEOLOCATION
UNION ALL
SELECT 'targeting_interest' AS table_name, COUNT(DISTINCT CONCAT(targeting_interest_ad_group_id, '|', targeting_interest_id)) AS workspace_count
FROM REDDIT_DBT_MODEL_GENERATION_PROD.WORKSPACE_MARKETING.WK_REDDIT_ADS_TARGETING_INTEREST
)
-- Abschließender Vergleich mit Validierungsergebnissen
SELECT
r.table_name,
r.raw_count,
w.workspace_count,
r.raw_count - w.workspace_count AS count_difference,
CASE
WHEN r.raw_count = w.workspace_count THEN '✅ BESTANDEN'
WHEN r.raw_count > w.workspace_count THEN '⚠️ RAW > WORKSPACE (Erwartet durch Deduplizierung)'
ELSE '❌ FEHLGESCHLAGEN - WORKSPACE > RAW (Unerwartet)'
END AS validation_status,
ROUND((w.workspace_count::FLOAT / r.raw_count::FLOAT) * 100, 2) AS data_retention_percentage
FROM raw_counts r
JOIN workspace_counts w ON r.table_name = w.table_name
ORDER BY r.table_name;
Die Ausführung dieser Abfrage zeigte:
-
Null Unterschiede in der Zeilenanzahl nach Deduplizierung
-
100% Datenerhaltung über alle Tabellen hinweg
-
Alle Tests erfolgreich bestanden
Das Fazit: Massive Zeitersparnis
-
Traditioneller Ansatz: 6-8 Stunden manuelles Programmieren, Testen und Debugging
-
GitLab Duo-Ansatz: 6-8 Minuten Generierung + Überprüfungszeit
Dies bedeutet eine 60-fache Verbesserung der Entwicklereffizienz (von 6-8 Stunden auf 6-8 Minuten) bei gleichbleibend hoher Codequalität.
Best Practices für den Erfolg
Basierend auf dieser Erfahrung sind hier die wichtigsten Empfehlungen:
Bereite deine Metadaten vor
-
Extrahiere vollständige Tabellenstrukturen einschließlich Datentypen und Einschränkungen
-
Identifiziere Primärschlüssel und Beziehungen im Voraus
-
Exportiere saubere, gut formatierte CSV-Eingabedateien
Hinweis: Durch die Verbindung von GitLab Duo über MCP mit deinen (Meta-)Daten könntest du diesen manuellen Schritt ausschließen.
Biete klaren Kontext
-
Referenziere nach Möglichkeit bestehende Beispiel-MRs
-
Spezifiziere deine Codierungsstandards und Style Guides
-
Sei explizit bei Ordnerstruktur und Namenskonventionen
Validiere gründlich
-
Erstelle immer Validierungsabfragen für die Datenintegrität
-
Teste lokal vor dem Mergen
-
Führe deine CI/CD-Pipeline aus, um Probleme zu erkennen
Nutze KI für Folgeaufgaben
-
Generiere Testabfragen automatisch
-
Erstelle Dokumentationsvorlagen
-
Baue Validierungsskripte
Was kommt als Nächstes
Diese Demonstration zeigt, wie KI-gestützte Entwicklungstools wie GitLab Duo auch Data-Engineering-Workflows transformieren. Die Fähigkeit, Hunderte von Zeilen produktionsreifem Code in Minuten zu generieren – komplett mit Tests, Dokumentation und ordnungsgemäßer Struktur – stellt einen fundamentalen Wandel dar, wie wir an repetitive Entwicklungsaufgaben herangehen.
Indem wir KI nutzen, um die repetitiven Aspekte der dbt-Modellerstellung zu bewältigen, können sich Dateningenieure auf Aktivitäten mit höherem Wert konzentrieren, wie Datenmodellierungsstrategie, Performance-Optimierung und Implementierung von Geschäftslogik.
Bereit, es selbst auszuprobieren? Beginne mit einem kleinen Datensatz, bereite deine Metadaten sorgfältig vor und sieh zu, wie GitLab Duo Stunden an Arbeit in Minuten automatisierter Generierung verwandelt.