dbt SQL ELT Modern Data Stack

dbt: SQL'i Bir Yazılım Projesine Dönüştürmek

Transformation katmanınız hâlâ elle çalıştırılan stored procedure'lardan mı oluşuyor? dbt'nin neden bu sektörde standart haline geldiğini, nasıl çalıştığını ve gerçekte ne zaman kullanmanız gerektiğini anlatalım.

BE
Batuhan Erdeniz | 11 Mayıs 2026 | 9 dk okuma

Sorun: Transformation katmanı her yerde, hiçbir yerde

Tipik bir veri ekibinin transformation katmanına bakın. Bazı dönüşümler ADF pipeline'larının içine gömülmüş. Bazıları SSMS'de el ile çalıştırılan stored procedure'lar. Birkaçı Excel'de. Bir kısmı Power BI'ın içinde Power Query olarak. Kimse tam resmi bilmiyor.

Bu dağınıklık küçük takımlarda başlar ama büyür. Bir gün müşteri tanımı değişir — "aktif müşteri" artık son 30 değil son 60 gün içinde alışveriş yapan müşteri anlamına gelir — ve bu değişikliği 7 farklı yerde güncellemeniz gerekir. Ve muhtemelen 2 tanesini unutursunuz.

Klasik anti-pattern: Transformation mantığı birden fazla araç ve katmana dağılmış. Hangi kodun "doğru" olduğunu kimse bilmiyor, kimse değiştirmeye cesaret edemiyor.

dbt tam olarak ne yapıyor?

dbt (data build tool), transformation katmanını — yani ham veriden analitik tablolara giden tüm SQL dönüşümlerini — tek bir yerde, versiyon kontrolüyle, test edilebilir ve belgelenebilir hale getiren açık kaynak bir araçtır.

dbt sadece T yapar. Extract ve Load kısmına karışmaz. Filocraft, Airbyte, ADF veya başka bir araçla veriyi warehouse'a attıktan sonra, dbt devreye girer ve SQL modellerinizi çalıştırır.

ETL değil, ELT: Önce yükle (Load), sonra dönüştür (Transform). Warehouse güçlüyse — Snowflake, BigQuery, Redshift, hatta SQL Server — dönüşümü orada yapmak hem daha hızlı hem de daha izlenebilir.

Katman mimarisi: Medallion'ın SQL hali

dbt projelerinde yaygın olarak kullanılan katman yapısı şudur:

Sources / Raw Ham veri — dokunma
Staging (stg_) 1:1 kaynak yansıması, tip cast, rename
Intermediate (int_) İş mantığı, join'ler, aggregation
Mart (dim_ / fct_) BI araçlarına açık son tablolar

Bu yapı Kimball'ın dimensional modeling felsefesiyle uyumludur. Staging katmanı kaynağı temizler ama iş mantığı eklemez. Mart katmanı iş kullanıcısının anlayabileceği tablolardır. Intermediate katmanı ise bu ikisi arasındaki karmaşık dönüşümleri izole eder.

Model nedir, nasıl yazılır?

dbt'de her SQL dosyası bir modeldir. Her model bir tablo veya view haline gelir. Bağımlılıklar ref() fonksiyonuyla tanımlanır — böylece dbt hangi modelin hangisinden önce çalışması gerektiğini otomatik çözer.

Staging modeli örneği

-- models/staging/stg_orders.sql
WITH source AS (
    SELECT * FROM {{ source('raw', 'orders') }}
),

renamed AS (
    SELECT
        order_id,
        customer_id,
        order_date::DATE                    AS order_date,
        total_amount_cents / 100.0          AS total_amount,
        LOWER(status)                       AS status,
        created_at
    FROM source
    WHERE order_date >= '2020-01-01'   -- iş kuralı değil, veri kalitesi filtresi
)

SELECT * FROM renamed

Fact tablosu örneği

-- models/marts/fct_orders.sql
WITH orders AS (
    SELECT * FROM {{ ref('stg_orders') }}
),

customers AS (
    SELECT * FROM {{ ref('stg_customers') }}
),

final AS (
    SELECT
        o.order_id,
        o.order_date,
        o.total_amount,
        o.status,
        c.customer_id,
        c.customer_segment,
        c.country
    FROM orders o
    LEFT JOIN customers c ON o.customer_id = c.customer_id
)

SELECT * FROM final

ref('stg_orders') ifadesi dbt'ye "bu model stg_orders'a bağımlıdır, önce onu çalıştır" der. Çalıştırma sırası, parallelization ve dependency resolution tamamen otomatiktir.

Gerçek güç: Test ve Dokümantasyon

Schema testleri

dbt'nin en değerli özelliklerinden biri yerleşik veri kalitesi testleridir. Her sütun için YAML dosyasında kurallar tanımlarsınız:

# models/marts/schema.yml
version: 2

models:
  - name: fct_orders
    columns:
      - name: order_id
        tests:
          - unique
          - not_null

      - name: status
        tests:
          - accepted_values:
              values: ['pending', 'completed', 'cancelled', 'refunded']

      - name: customer_id
        tests:
          - not_null
          - relationships:
              to: ref('dim_customers')
              field: customer_id

dbt test komutunu çalıştırdığınızda tüm bu kurallar warehouse'da SQL sorgularına dönüşür ve çalıştırılır. CI/CD'ye bağlarsanız, bozuk veriyi production'a geçmeden önce yakalarsınız.

Gerçek hayat değeri: "Bu tablodaki order_id'ler unique mi?" sorusunu artık elle sormuyorsunuz. Her deployment'ta otomatik kontrol edilir. Veri analistleri tablolara güvenmeye başlar.

Otomatik dokümantasyon

dbt docs generate komutu tüm modellerinizi, sütunlarınızı ve bağımlılıklarınızı tarayarak bir web arayüzü oluşturur. DAG görselleştirmesiyle hangi modelin hangi kaynaktan beslendiğini tek bakışta görebilirsiniz. Yeni bir veri mühendisi takıma katıldığında onboarding süresi dramatik biçimde kısalır.

dbt Core vs dbt Cloud

dbt Core (Açık Kaynak)

- Tamamen ücretsiz
- CLI tabanlı
- Git entegrasyonu kendinize
- Orchestration kendinize
  (Airflow, Prefect vb.)
- CI/CD kurulumu kendinize
- Metadata yönetimi kendinize

Kimler kullanır:
Kendi altyapısı olan,
DevOps kapasitesi yüksek
data engineering ekipleri

dbt Cloud

- Ücretli (developer plan ücretsiz)
- Web IDE + scheduler dahil
- Git entegrasyonu hazır
- Job orchestration yerleşik
- CI/CD otomatik
- Explorer (dokümantasyon UI)

Kimler kullanır:
Hızlı başlamak isteyen,
DevOps yükünü azaltmak
isteyen takımlar

Küçük ve orta ölçekli şirketlerin büyük çoğunluğu dbt Cloud'dan başlar. Zaten Snowflake veya BigQuery kullanıyorsanız, ekstra infra yönetmeden değer almak için mantıklı bir tercih. Kurumsal ortamda, özellikle on-premise SQL Server üzerinde çalışıyorsanız, dbt Core + Airflow kombinasyonu daha yaygın.

SQL Server / Azure Synapse kullanıcılarına not: dbt, SQL Server ve Azure Synapse Analytics'i destekler (dbt-sqlserver ve dbt-synapse adapter'ları). SSAS Tabular ile direkt entegrasyonu yoktur — dbt warehouse katmanını yönetir, semantic layer değil. Kombine kullanımda dbt çıktıları SSAS'ın veri kaynağı olur.

Ne zaman dbt kullanmalısınız?

dbt her zaman doğru araç değil. Şu kriterlere bakın:

Stored procedure'lardan geçiş nasıl yapılır?

Mevcut bir pipeline'ı dbt'ye taşımanın en az riskli yolu incremental migrationdır. Tüm stored procedure'ları bir gecede dönüştürmeye çalışmayın.

  1. Yeni bir model yazarken dbt ile başlayın. Mevcut olanları dokunmadan bırakın.
  2. Staging katmanını önce oluşturun. En az iş mantığı içerdiği için en güvenli başlangıç noktasıdır.
  3. Her yeni mart tablosu için dbt kullanın. Stored procedure'u deprecated olarak işaretleyin ama silmeyin henüz.
  4. Sonuçlar eşleştiğinde eski prosedürü kaldırın.
-- dbt_project.yml — Projenin kök yapılandırması
name: 'my_data_project'
version: '1.0.0'
config-version: 2

profile: 'my_sqlserver_profile'

model-paths: ["models"]
test-paths: ["tests"]
docs-paths: ["docs"]

models:
  my_data_project:
    staging:
      +materialized: view       # Staging'i view bırak, depolama maliyeti düşük
    intermediate:
      +materialized: view
    marts:
      +materialized: table      # Mart'ları tablo olarak materialize et
Sonuç: dbt, SQL transformation'ı yazılım mühendisliğinin standartlarına taşır: versiyon kontrolü, test, dokümantasyon, modülerlik. Eğer takımınız hâlâ "bu stored procedure kim yazmış, dokunma" kültüründeyse, dbt bu kültürü kırmak için güçlü bir başlangıç noktasıdır.

Sıradaki yazıda

dbt'yi SSAS Tabular ile birlikte kullanan bir enterprise mimarisi üzerine yazmayı planlıyorum — warehouse katmanını dbt yönetirken semantic layer'ı SSAS'ta tutmak ne zaman mantıklı, ne zaman overkill?

Soru ya da benzer bir geçiş süreciyle mi uğraşıyorsunuz? LinkedIn'den ulaşabilirsiniz.