dbt nedir? Analytics engineering rehberi
2026 · analytics engineering · 20 dakika okuma
Veri mühendisleri veriyi taşır. Veri analistleri veriyi analiz eder. Peki ikisi arasında kim veriyi analiz için hazırlar? İşte bu boşluğu dolduran rol: analytics engineer. Ve bu rolün en önemli aracı: dbt.
dbt nedir?
dbt (data build tool) veri ambarı içindeki transform katmanını yönetir. SQL biliyorsan dbt öğrenebilirsin — ek bir programlama dili gerekmez.
Temel fikir şu: ham veriyi veri ambarına yükle (EL adımı), dönüşümü dbt ile SQL yazarak veri ambarı içinde yap (T adımı). Bu yaklaşıma ELT denir.
Neden dbt?
dbt olmadan transform katmanı nasıl yönetilir? Genellikle şöyle:
- Karmaşık SQL sorguları Excel'e kopyalanır
- Kimse hangi sorgunun güncel olduğunu bilmez
- "Gelir" metriği farklı departmanlarda farklı hesaplanır
- Bir şeyi değiştirince başka şey bozulur, kimse fark etmez
dbt ile:
- Tüm transform SQL dosyalarında, Git'te versiyon kontrolünde
- Modeller birbirine bağlı, bağımlılıklar otomatik yönetilir
- Test yazılır — veri kalitesi otomatik kontrol edilir
- Dokümantasyon otomatik oluşur
Kurulum ve ilk proje
# dbt Core kurulumu (SQLite için) pip install dbt-core dbt-sqlite # Yeni proje oluştur dbt init sifir_gecikme_analytics # Proje yapısı sifir_gecikme_analytics/ ├── models/ # SQL modellerin burada │ ├── staging/ # Ham veriden ilk temizleme │ ├── intermediate/# Ara hesaplamalar │ └── marts/ # Son analiz tabloları ├── tests/ # Veri kalite testleri ├── seeds/ # Küçük CSV dosyaları ├── macros/ # Tekrar kullanılabilir SQL └── dbt_project.yml # Proje konfigürasyonu
İlk model — Staging
Staging modelleri ham veriyi temizler ve standardize eder. Her kaynak tablo için bir staging modeli yazılır.
-- models/staging/stg_orders.sql
-- Ham sipariş verisini temizle ve standardize et
WITH source AS (
-- Ham tablodan veriyi al
SELECT * FROM {{ source('raw', 'orders') }}
),
renamed AS (
SELECT
-- Sütun adlarını standardize et
id AS order_id,
customer_id,
created_at AS order_date,
status AS order_status,
total_price AS order_total,
-- Tip dönüşümleri
CAST(total_price AS DECIMAL(10,2)) AS order_total_clean,
DATE(created_at) AS order_date_only,
-- Hesaplamalar
CASE
WHEN status = 'completed' THEN TRUE
WHEN status = 'cancelled' THEN FALSE
ELSE NULL
END AS is_completed,
-- Metadata
CURRENT_TIMESTAMP AS dbt_updated_at
FROM source
WHERE id IS NOT NULL -- NULL primary key'leri çıkar
)
SELECT * FROM renamedIntermediate modeller
Ara hesaplamalar için kullanılır. Birden fazla staging modelini birleştirir, iş mantığını uygular.
-- models/intermediate/int_orders_with_customers.sql
-- Siparişleri müşteri bilgileriyle birleştir
WITH orders AS (
SELECT * FROM {{ ref('stg_orders') }}
),
customers AS (
SELECT * FROM {{ ref('stg_customers') }}
),
order_items AS (
SELECT * FROM {{ ref('stg_order_items') }}
),
-- Sipariş başına toplam hesapla
order_totals AS (
SELECT
order_id,
COUNT(*) AS item_count,
SUM(quantity) AS total_quantity,
SUM(quantity * price) AS calculated_total
FROM order_items
GROUP BY order_id
),
final AS (
SELECT
o.order_id,
o.order_date,
o.order_status,
-- Müşteri bilgileri
c.customer_id,
c.customer_name,
c.customer_city,
c.customer_segment,
-- Sipariş detayları
ot.item_count,
ot.total_quantity,
ot.calculated_total,
-- Türetilmiş metrikler
DATEDIFF('day', c.first_order_date, o.order_date) AS customer_age_at_order
FROM orders o
LEFT JOIN customers c USING (customer_id)
LEFT JOIN order_totals ot USING (order_id)
)
SELECT * FROM finalMart modeller — Son analiz tabloları
BI araçlarının doğrudan bağlandığı tablolar. Kullanıcıya göre organize edilir: finans mart, pazarlama mart, müşteri mart gibi.
-- models/marts/fct_monthly_revenue.sql
-- Aylık gelir gerçekler tablosu
WITH orders AS (
SELECT * FROM {{ ref('int_orders_with_customers') }}
WHERE order_status = 'completed'
),
monthly_agg AS (
SELECT
DATE_TRUNC('month', order_date) AS month,
customer_segment,
customer_city,
-- Metrikler
COUNT(DISTINCT order_id) AS order_count,
COUNT(DISTINCT customer_id) AS unique_customers,
SUM(calculated_total) AS total_revenue,
AVG(calculated_total) AS avg_order_value,
SUM(item_count) AS total_items_sold,
-- Büyüme (window fonksiyon)
SUM(calculated_total) / LAG(SUM(calculated_total)) OVER (
PARTITION BY customer_segment
ORDER BY DATE_TRUNC('month', order_date)
) - 1 AS mom_growth_rate
FROM orders
GROUP BY 1, 2, 3
)
SELECT * FROM monthly_agg
ORDER BY month DESC, total_revenue DESCdbt testleri
Veri kalitesini otomatik test etmek dbt'nin en güçlü özelliklerinden biri. İki tür test var: genel (built-in) ve özel.
# models/staging/schema.yml
# YAML dosyasında test tanımları
version: 2
models:
- name: stg_orders
description: "Temizlenmiş sipariş veritabanı"
columns:
- name: order_id
description: "Benzersiz sipariş ID"
tests:
- unique # Tekrar yok mu?
- not_null # NULL var mı?
- name: order_status
tests:
- accepted_values:
values: ['pending', 'completed', 'cancelled', 'refunded']
- name: customer_id
tests:
- not_null
- relationships: # Foreign key kontrolü
to: ref('stg_customers')
field: customer_id
- name: order_total
tests:
- not_null
- dbt_utils.accepted_range:
min_value: 0
max_value: 1000000# Testleri çalıştır dbt test # Sadece bir modeli test et dbt test --select stg_orders # Çıktı örneği: # 12:34:56 | 1 of 4 START test not_null_stg_orders_order_id [RUN] # 12:34:56 | 1 of 4 PASS not_null_stg_orders_order_id [PASS in 0.12s] # 12:34:56 | 2 of 4 START test unique_stg_orders_order_id [RUN] # 12:34:56 | 2 of 4 PASS unique_stg_orders_order_id [PASS in 0.09s]
Makrolar — Tekrar kullanılabilir SQL
Jinja şablonlama ile SQL içinde fonksiyon yazabilirsin. Tekrar eden kod bloklarını makro olarak tanımla.
-- macros/cents_to_tl.sql
-- Kuruşu TL'ye çeviren makro
{% macro cents_to_tl(column_name) %}
({{ column_name }} / 100.0)
{% endmacro %}
-- macros/is_weekend.sql
{% macro is_weekend(date_column) %}
CASE
WHEN DAYOFWEEK({{ date_column }}) IN (1, 7) THEN TRUE
ELSE FALSE
END
{% endmacro %}
-- Kullanım:
-- SELECT {{ cents_to_tl('total_price') }} AS total_tl
-- SELECT {{ is_weekend('order_date') }} AS is_weekenddbt ile çalışma akışı
# Modelleri çalıştır dbt run # Sadece bir modeli çalıştır dbt run --select fct_monthly_revenue # Model ve bağımlılarını çalıştır dbt run --select +fct_monthly_revenue # Testleri çalıştır dbt test # Dokümantasyon oluştur ve aç dbt docs generate dbt docs serve # Seed dosyalarını yükle (küçük CSV'ler) dbt seed # Hepsini sırayla çalıştır dbt build
Proje klasör yapısı — Gerçek dünya
analytics/ ├── models/ │ ├── staging/ # 1. katman — ham veri temizleme │ │ ├── _sources.yml # Kaynak tanımları │ │ ├── stg_orders.sql │ │ ├── stg_customers.sql │ │ └── stg_products.sql │ │ │ ├── intermediate/ # 2. katman — iş mantığı │ │ ├── int_orders_enriched.sql │ │ └── int_customer_lifetime.sql │ │ │ └── marts/ # 3. katman — son tablolar │ ├── finance/ │ │ ├── fct_revenue.sql │ │ └── fct_refunds.sql │ ├── marketing/ │ │ ├── fct_campaigns.sql │ │ └── dim_customers.sql │ └── product/ │ └── fct_feature_usage.sql │ ├── macros/ # Tekrar kullanılabilir SQL ├── seeds/ # Statik referans verileri ├── tests/ # Özel testler ├── analyses/ # Ad-hoc analizler (deploy edilmez) └── dbt_project.yml
dbt Cloud vs dbt Core
Başlangıç için dbt Cloud'un ücretsiz planını öneririm. Kurulum yok, tarayıcıdan çalışır, hemen başlarsın. getdbt.com/signup → 5 dakikada hazır.
Özet
- dbt veri ambarı içinde SQL ile transform yapar
- Modeller staging → intermediate → marts hiyerarşisinde organize edilir
- Testler veri kalitesini otomatik kontrol eder
- ref() modeller arası bağımlılıkları yönetir
- Git entegrasyonu ile tüm değişiklikler versiyonlanır
- Başlamak için dbt Cloud ücretsiz plan yeterli
Önceki yazı: ETL nedir? Veriyi taşımanın sistematik yolu