Macros & Packages
Macros and Packages
Bu derste neler öğreneceksin
- Jinja macro yazar
- dbt_utils paketi kullanır
- Topluluk paketlerini keşfeder
Neden Macro?
Production’da onlarca modelde aynı SQL parçası tekrar eder:
WHERE created_at >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)— “son 90 gün filtresi” her staging’de.NULLIF(LOWER(TRIM(email)), '')— email normalizasyonu.COALESCE(kampanya_id, 'organik')— default kategori.
Bunları macro olarak yazarsın, tek yerde değiştirirsin, yüz modelde uygulanır. Jinja dili Python benzeri: {% %} bloklar, {{ }} ifadeler.
İlk Macro: “Son N Gün”
macros/son_n_gun.sql:
{% macro son_n_gun(alan, n=30) %}
{{ alan }} >= DATE_SUB(CURRENT_DATE(), INTERVAL {{ n }} DAY)
{% endmacro %}
Modelde kullanımı:
SELECT *
FROM {{ source('raw', 'siparisler') }}
WHERE {{ son_n_gun('siparis_tarihi', 90) }}
dbt derlerken son_n_gun çağrısını açık SQL’e çevirir. Default n=30, istersen override et.
Macro with Logic: Kontrol Flow
Jinja ile koşul ve döngü yazabilirsin:
{% macro pivot_kanal(kanallar) %}
{% for k in kanallar %}
SUM(CASE WHEN kanal = '{{ k }}' THEN toplam_tutar ELSE 0 END) AS ci_{{ k | lower }}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endmacro %}
Modelde:
SELECT
siparis_gunu,
{{ pivot_kanal(['POS', 'ECOM', 'PHONE']) }}
FROM {{ ref('fct_gunluk_siparis') }}
GROUP BY siparis_gunu
Çıktı:
SELECT
siparis_gunu,
SUM(CASE WHEN kanal = 'POS' THEN toplam_tutar ELSE 0 END) AS ci_pos,
SUM(CASE WHEN kanal = 'ECOM' THEN toplam_tutar ELSE 0 END) AS ci_ecom,
SUM(CASE WHEN kanal = 'PHONE' THEN toplam_tutar ELSE 0 END) AS ci_phone
FROM ...
{% if not loop.last %} son kolon olmadığını kontrol edip virgül ekler — temiz SQL çıktısı.
Adapter Dispatch: Cross-Warehouse Macros
BigQuery DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY) kullanır, ama Postgres CURRENT_DATE - INTERVAL '90 days' ister, Snowflake farklı. dbt’nin adapter.dispatch mekanizması macro’yu adapter’a göre farklı yazar:
macros/tarih_farki.sql:
{% macro tarih_farki_gun(gun) %}
{{ return(adapter.dispatch('tarih_farki_gun', 'limonata_analiz')(gun)) }}
{% endmacro %}
macros/bigquery__tarih_farki_gun.sql:
{% macro bigquery__tarih_farki_gun(gun) %}
DATE_SUB(CURRENT_DATE(), INTERVAL {{ gun }} DAY)
{% endmacro %}
macros/postgres__tarih_farki_gun.sql:
{% macro postgres__tarih_farki_gun(gun) %}
CURRENT_DATE - INTERVAL '{{ gun }} days'
{% endmacro %}
Aynı macro, hangi adapter ile çalışıyorsan onun syntax’ını üretir. Birden fazla warehouse destekleyen paket yazıyorsan bu şart.
Packages: Topluluk Kütüphanesi
dbt_utils — olmazsa olmaz
packages.yml:
packages:
- package: dbt-labs/dbt_utils
version: [">=1.1.0", "<2.0.0"]
dbt deps
En sık kullanılan macro’lar:
dbt_utils.surrogate_key: Birden çok sütunu birleştiripmd5ile benzersiz kimlik üretir.dbt_utils.date_spine: Tarih aralığı için eksiksiz gün listesi üretir (gap’siz dimension tablo).dbt_utils.pivot: Dinamik sütun-dönüşümü (satır → sütun).dbt_utils.union_relations: Aynı şemadaki birden çok tabloyu birleştirir.dbt_utils.deduplicate: ORDER BY + ROW_NUMBER ile tekilleştirme.dbt_utils.expression_is_true: Custom assertion testi.
Örnek: date_spine
{{ dbt_utils.date_spine(
datepart="day",
start_date="cast('2024-01-01' as date)",
end_date="cast('2024-12-31' as date)"
) }}
Sonuç: 2024-01-01’den 2024-12-31’e kadar her gün için bir satır. Aktif olmayan günleri de içeren “calendar” tablosu yapmak için ideal.
dbt_expectations — gelişmiş testler
columns:
- name: toplam_tutar
tests:
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
strictly: true
- dbt_expectations.expect_column_mean_to_be_between:
min_value: 50
max_value: 500
- dbt_expectations.expect_column_values_to_match_regex:
regex: "^[A-Z]{3}-[0-9]+$"
50+ test: istatistiksel (mean, stddev), format (regex, length), dağılım (percentile).
Diğer Faydalı Paketler
codegen: Mevcut tablodan YAML şema üret.audit_helper: İki modelin çıktısını karşılaştır (schema diff, value diff).dbt_project_evaluator: Proje sağlığını denetler (kullanılmayan modeller, eksik test, vb.).elementary: Test sonuçlarını görsel dashboard’a yazar (data observability).grouparoo: Reverse-ETL (warehouse’dan operasyonel sisteme veri yaz).
Ne Öğrendik?
- Macro = Jinja-templated SQL parçası, tek yerde yazılıp yerde kullanılır.
- Adapter dispatch ile cross-warehouse uyumlu macro yazılır.
- Packages topluluk tarafından bakılan yeniden kullanılabilir kod.
- dbt_utils en temel paket (pivot, surrogate_key, date_spine, union_relations).
- dbt_expectations 50+ test ile veri kalitesi güvencesi.
Küçük Ödev
son_n_gunmacro’sunu yaz, 5 staging modelinde uygula.packages.yml’edbt_utilsekle,dbt depsçalıştır.dbt_utils.date_spineile 2024 boyunca dim_takvim modeli oluştur.dbt_utils.surrogate_keyile benzersiz müşteri_gun_id üreten bir model yaz.