dlt ile ilk ingestion: 5 dakikada API'den tabloya
dlt first ingestion
Bu derste neler öğreneceksin
- dlt init dlthub:open_library duckdb çalıştırır
- Open Library API den veri çeker
- Normalize edilmiş tabloyu inceler
Modern Ingestion Stack
Veri alımı (ingestion) veri mühendisliğinin ilk ve en kritik katmanı. Geleneksel yaklaşım: saatlerce requests + manuel JSON parse + INSERT SQL’leri yaz. Modern yaklaşım: declarative (bildirimsel) — ne istediğini söyle, araç gerisini halletsin.
dlt (data load tool) bu felsefenin Python implementasyonu. Bir dlt pipeline:
- Bir kaynak (API, dosya, veritabanı) tanımla.
- dlt şemayı otomatik çıkarsın.
- Veriyi normalize edip destination’a yaz (DuckDB, BigQuery, Snowflake, Postgres).
- State (nerede kaldın) ve schema evolution (yeni sütunlar) otomatik yönetilir.
Bugün bu akışı uçtan uca göreceğiz. Source: Open Library REST API. Destination: DuckDB. Tüm süreç: ~50 satır Python.
Kurulum
pip install "dlt[duckdb]"
dlt[duckdb] ekstra etiketi, DuckDB destination’ı için gerekli driver’ı kurar. Diğer backend’ler (BigQuery, Snowflake, Postgres) kendi ekstralarıyla gelir.
Open Library Source’unu İncele
Open Library ücretsiz, açık bir kitap metadata API’si. URL:
https://openlibrary.org/search.json?q=harry+potter&page=1
JSON yanıtı iç içe (nested) ve heterojen (her kitap farklı alanlar içerebilir). Bu, gerçek dünya API’lerinin tipik özelliği — temiz CSV gibi gelenler nadirdir.
Elle yazsan: response’u parse et, normalize et, INSERT yaz, pagination hallet, rate limit’e dikkat et, … 200-300 satır kod.
dlt ile: 20 satır.
İlk Pipeline
ingest_open_library.py:
import dlt
from dlt.sources.helpers.rest_client import RESTClient
from dlt.sources.helpers.rest_client.paginators import PageNumberPaginator
# Kaynak: REST API client
client = RESTClient(
base_url="https://openlibrary.org",
# İstersen auth, headers, retry buraya eklenir
)
@dlt.resource(
table_name="books",
name="harry_potter_books",
write_disposition="replace", # her çalıştırmada tabloyu yenile
)
def harry_potter_books():
"""Open Library'den Harry Potter kitaplarını paginate et."""
for page in client.paginate(
"/search.json",
params={"q": "harry potter", "limit": 100},
paginator=PageNumberPaginator(base_page=1, total_path=None),
):
# API her sayfada {docs: [...], num_found: N} döner
# dlt otomatik docs içindeki her kaydı bir satır yapar
yield page.get("docs", [])
# Destination'a yaz
pipeline = dlt.pipeline(
pipeline_name="open_library",
destination="duckdb",
dataset_name="raw_books",
progress="log", # ilerleme log'u
)
load_info = pipeline.run(harry_potter_books())
print(load_info)
Çalıştır: python ingest_open_library.py. Çıktıda:
- Kaç sayfa çekildi
- Kaç kayıt normalize edildi
- Hangi tablolar oluştu
- Yükleme süresi
Schema Inference ve Normalization
dlt’in en güçlü özelliği. Response’u oku, alanları incele, otomatik:
- Primary table (
books) ana alanları içerir. - Nested arrays (
author_name,isbn,subject) ayrı child tablolara ayrılır, FK ile bağlanır. - Type coercion: yıl
int, başlıktext, listearrayveya relation table. - Missing fields eksik olarak işaretlenir, hata vermez.
Sonuç: dlt’in kendi öğrendiği bir şema, hem tip güvenli hem sorgulanabilir.
İncelemek için:
dlt pipeline open_library show
Açılan browser’da:
- Tablolar listesi (sütun sayısı, satır sayısı)
- Her tablonun şeması (veri tipi dahil)
- Örnek satırlar
- Load info: son yüklemenin özeti (hata varsa kırmızı, başarı yeşil)
Bu UI, production’da hata ayıklamanın en hızlı yolu.
Production’a Taşıma: Neden Önemli?
Bir startup hayal et. İlk gün DuckDB’de deniyorsun (tek dosya, sıfır infra). 6 ay sonra milyonlarca kitap, yüzlerce GB — DuckDB yetmiyor. destination=“duckdb” satırını destination=“bigquery” ile değiştir, GCP service account JSON’u env’e koy, bitti. Hiçbir pipeline kodu değişmedi.
Bu portability (taşınabilirlik) dlt’in en güçlü satış noktası. Vendor lock-in’den kaçınırsın.
Incrementals: Aynı Komutu Tekrar Çalıştır
write_disposition="replace" her seferinde siler-yazar. Production’da istemezsin — sadece yeni gelenleri eklemek istersin:
@dlt.resource(
table_name="books",
write_disposition="merge", # upsert: varsa güncelle, yoksa ekle
primary_key="key", # Open Library unique ID
)
def harry_potter_books():
...
merge mode, Open Library’nin son güncellemelerini yakalar. Incremental loading olarak bilinir — veri miktarı büyüdükçe hayati.
Hands-on
q="harry potter"yerine kendi ilgi alanını koy (örn.q="machine learning").- Çalıştır, kaç kitap geldiğini not al.
dlt pipeline ... showile tabloları incele.write_disposition="replace"->"merge"değiştir, tekrar çalıştır, satır sayısı değişmedi mi kontrol et.
Sıradaki
Ingestion çalışıyor. Ama veri kalitesini nasıl garanti ederiz? →