Sz
Sıfır Gecikme
veri bilimi · türkçe
Hakkımda🗺️ Haritam
Tümü
İnteraktif📖Rehber🛠Araç📊Vaka💼Kariyer🐍PY Playground🗄️SQL Playground🔍Regex📚Öğren🚀Proje
Ana sayfarehber

ETL nedir? Veriyi taşımanın sistematik yolu

2026 · data engineering · 18 dakika okuma

Veri nerede üretilir? Genellikle üretim veritabanlarında, API'lerde, dosyalarda, log sistemlerinde. Analiz nerede yapılır? Veri ambarında, BI araçlarında, Jupyter notebook'ta. Bu iki nokta arasındaki köprü ETL.

ETL nedir?

ETL üç adımın kısaltması: Extract (Çıkar), Transform (Dönüştür), Load (Yükle). Ham veriyi kaynak sistemden alıp, analiz için hazır hale getirip, hedef sisteme yüklemek.

E
Extract
Kaynak sistemden veriyi çek. Veritabanı, API, CSV, Excel, log dosyası...
T
Transform
Veriyi temizle, birleştir, hesapla. İş kurallarını uygula.
L
Load
Hazır veriyi hedefe yükle. Veri ambarı, BI aracı, dashboard.

Neden ETL gerekli?

Çoğu şirkette veri farklı sistemlerde dağınık halde bulunur. Satış verisi CRM'de, ürün verisi ERP'de, web trafiği Google Analytics'te, müşteri yorumları ayrı bir platformda. Bunları birleştirmeden anlamlı analiz yapamazsın.

Üstelik üretim veritabanları analiz için optimize edilmemiştir. Sorgu çalıştırınca canlı sistemi yavaşlatırsın. ETL ile veriyi ayrı bir analiz ortamına taşırsın.

1. Extract — Veriyi çekme

Kaynak sistemden veriyi almak. En yaygın senaryolar:

import pandas as pd
import sqlite3
import requests

# ── Veritabanından çekme ──────────────────────────────
conn = sqlite3.connect('uretim.db')
df_siparisler = pd.read_sql("""
    SELECT s.id, s.tarih, s.musteri_id, s.toplam
    FROM siparisler s
    WHERE s.tarih >= '2024-01-01'
""", conn)
conn.close()

# ── CSV / Excel'den çekme ─────────────────────────────
df_urunler = pd.read_csv('urunler.csv')
df_butce   = pd.read_excel('butce_2024.xlsx', sheet_name='Q1')

# ── API'den çekme ─────────────────────────────────────
response = requests.get(
    'https://api.orneksite.com/musteriler',
    headers={'Authorization': 'Bearer TOKEN'},
    params={'limit': 1000, 'offset': 0}
)
df_musteriler = pd.DataFrame(response.json()['data'])

print(f"Siparişler: {df_siparisler.shape}")
print(f"Ürünler:    {df_urunler.shape}")
print(f"Müşteriler: {df_musteriler.shape}")

2. Transform — Dönüştürme

ETL'nin kalbi burada. Ham veriyi analiz için hazır hale getirmek: temizleme, birleştirme, hesaplama, standardize etme.

import pandas as pd
import numpy as np

# ── Temel temizleme ───────────────────────────────────
def temizle(df):
    df = df.copy()

    # Sütun adlarını standardize et
    df.columns = (df.columns
        .str.strip()
        .str.lower()
        .str.replace(' ', '_'))

    # Tekrar eden satırları sil
    df = df.drop_duplicates()

    # Tarih sütunlarını dönüştür
    for col in df.columns:
        if 'tarih' in col or 'date' in col:
            df[col] = pd.to_datetime(df[col], errors='coerce')

    return df

# ── İş kuralları uygula ───────────────────────────────
def is_kurallari_uygula(df_siparisler, df_urunler):
    # Birleştir
    df = df_siparisler.merge(
        df_urunler[['id', 'kategori', 'maliyet']],
        left_on='urun_id',
        right_on='id',
        how='left'
    )

    # Hesaplamalar
    df['kar'] = df['satis_fiyati'] - df['maliyet']
    df['kar_marji'] = (df['kar'] / df['satis_fiyati'] * 100).round(2)
    df['ay'] = df['siparis_tarihi'].dt.to_period('M')
    df['yil'] = df['siparis_tarihi'].dt.year

    # Kategorik dönüşüm
    df['segment'] = pd.cut(
        df['toplam'],
        bins=[0, 500, 2000, 10000, float('inf')],
        labels=['Küçük', 'Orta', 'Büyük', 'Kurumsal']
    )

    return df

# ── Aggregation (özetleme) ────────────────────────────
def aylik_ozet_olustur(df):
    return df.groupby(['ay', 'kategori']).agg(
        siparis_sayisi=('id', 'count'),
        toplam_ciro=('toplam', 'sum'),
        ort_siparis=('toplam', 'mean'),
        toplam_kar=('kar', 'sum'),
        ort_kar_marji=('kar_marji', 'mean'),
    ).round(2).reset_index()

3. Load — Hedefe yükleme

Dönüştürülmüş veriyi analiz ortamına yükle. Hedef bir SQL veritabanı, Parquet dosyası, Google BigQuery veya BI aracı olabilir.

import pandas as pd
import sqlite3

# ── SQLite'a yükle (geliştirme/test) ─────────────────
def sqlite_yukle(df, tablo_adi, db_yolu='analiz.db'):
    conn = sqlite3.connect(db_yolu)
    df.to_sql(
        tablo_adi,
        conn,
        if_exists='replace',   # 'replace', 'append', 'fail'
        index=False,
        chunksize=1000         # büyük veri için toplu yükleme
    )
    conn.close()
    print(f"✓ {len(df):,} satır → {tablo_adi}")

# ── Parquet'a yükle (hızlı, sıkıştırılmış) ───────────
def parquet_yukle(df, dosya_yolu):
    df.to_parquet(
        dosya_yolu,
        engine='pyarrow',
        compression='snappy',
        index=False
    )
    print(f"✓ Kaydedildi: {dosya_yolu}")

# ── CSV olarak arşivle ────────────────────────────────
def arsivle(df, klasor='arsiv'):
    import os
    from datetime import datetime
    os.makedirs(klasor, exist_ok=True)
    tarih = datetime.now().strftime('%Y%m%d_%H%M')
    yol = f"{klasor}/veri_{tarih}.csv"
    df.to_csv(yol, index=False)
    print(f"✓ Arşivlendi: {yol}")

Tam ETL pipeline

Gerçek dünyada tüm adımları birleştiren, hata yönetimine sahip, loglama yapan bir pipeline şöyle görünür:

import pandas as pd
import sqlite3
import logging
from datetime import datetime

# Loglama ayarla
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
log = logging.getLogger(__name__)

def etl_calistir():
    baslangic = datetime.now()
    log.info("ETL pipeline başladı")

    try:
        # ── EXTRACT ──────────────────────────────────
        log.info("Veri çekiliyor...")
        conn = sqlite3.connect('uretim.db')
        df = pd.read_sql(
            "SELECT * FROM siparisler WHERE tarih >= date('now', '-30 days')",
            conn
        )
        conn.close()
        log.info(f"  ✓ {len(df):,} satır çekildi")

        # ── TRANSFORM ────────────────────────────────
        log.info("Dönüştürme başlıyor...")

        # Temizle
        df = df.drop_duplicates()
        df['tarih'] = pd.to_datetime(df['tarih'])
        df['toplam'] = pd.to_numeric(df['toplam'], errors='coerce')
        df = df.dropna(subset=['toplam', 'tarih'])

        # Hesapla
        df['ay'] = df['tarih'].dt.to_period('M').astype(str)
        df['hafta'] = df['tarih'].dt.isocalendar().week

        # Özetle
        ozet = df.groupby('ay').agg(
            siparis_sayisi=('id', 'count'),
            toplam_ciro=('toplam', 'sum'),
        ).reset_index()

        log.info(f"  ✓ {len(df):,} satır dönüştürüldü")

        # ── LOAD ──────────────────────────────────────
        log.info("Yükleniyor...")
        analiz_conn = sqlite3.connect('analiz.db')
        df.to_sql('siparisler_temiz', analiz_conn,
                  if_exists='replace', index=False)
        ozet.to_sql('aylik_ozet', analiz_conn,
                    if_exists='replace', index=False)
        analiz_conn.close()
        log.info("  ✓ Yükleme tamamlandı")

        # Özet rapor
        sure = (datetime.now() - baslangic).seconds
        log.info(f"ETL tamamlandı — {sure}s | {len(df):,} satır")
        return True

    except Exception as e:
        log.error(f"ETL HATASI: {e}")
        raise

if __name__ == '__main__':
    etl_calistir()

ETL vs ELT

Modern veri ambarları (BigQuery, Snowflake, Redshift) çok güçlü. Bu yüzden son yıllarda ELT (Extract, Load, Transform) yaygınlaştı — önce ham veriyi yükle, dönüşümü ambar içinde yap.

ETL
Dönüşüm pipeline dışında yapılır
On-premise sistemlerde yaygın
Hassas veri için güvenli
Python / Spark ile
ELT
Dönüşüm ambar içinde yapılır
Cloud sistemlerde yaygın
dbt ile transform yazılır
BigQuery / Snowflake ile

Popüler ETL araçları

Altın kurallar

Sıradaki yazıda dbt ile analytics engineering: SQL ile transform katmanı nasıl yazılır, veri modelleri nasıl oluşturulur.

Bunları da beğenebilirsin

rehber

Pandas'ta en çok yanlış bilinen 7 şey

15 dakika

rehber

Feature engineering: modelden önce gelen sanat

15 dakika

rehber

SQL temelleri: veri analistinin en önemli becerisi

20 dakika

Faydalı bulduysan paylaş

X'te paylaşLinkedIn'de paylaş

💬 Yorumlar