A dbt Python modellek lehetővé teszik, hogy Python kódot futtass közvetlenül az adattárházban (Snowflake-en Snowparkkal, Databricks-en PySparkkal, BigQuery-n BigFrames-szel), anélkül, hogy külön orchestrationt kellene fenntartanod. A model függvényed egy DataFrame-et ad vissza, dbt pedig kezeli a materializációt, a lineage-et, a teszteket és a dokumentációt. Három éve élek dbt-vel produkción, és őszintén, a Python modellek pontosan azt a rést töltik be, amit korábban ad hoc scriptekkel foltoztunk: ML feature engineering, szöveg-normalizálás, gráfelemzés, és minden, amit SQL-ben már nem éri meg leírni.
A dbt Python modell egy .py fájl a models/ mappában, egyetlen model(dbt, session) függvénnyel, amely DataFrame-et ad vissza.
Támogatott platformok 2026-ban: Snowflake (Snowpark), Databricks (PySpark), BigQuery (BigFrames). A view és ephemeral materializáció NEM támogatott, csak table és incremental.
Inkrementális Python modellhez a dbt.is_incremental flaggel szűrsz a dbt.this táblához képest, pontosan úgy, mint SQL-ben.
A unique, not_null és accepted_values generic tesztek Python modellekre is működnek YAML-ből, külön SQL tesztet nem kell írni hozzájuk.
Teljesítmény: mindig a natív DataFrame API-t használd (Snowpark, PySpark), és csak akkor konvertálj pandasra, ha muszáj. A .to_pandas() hívás a warehouse execution engine-t megkerüli.
Költség: a Python modellek drágábbak, mint az SQL-ek, mert general-purpose compute-on futnak. Szűrj korán, join-olj feljebb, futass inkrementálisan.
Mi az a dbt Python modell és mikor érdemes használni?
A dbt Python modell egy transzformáció, amit Python nyelven írsz meg, de a dbt fordítja le a célplatform Python runtime-jára, és pontosan úgy kezel, mint egy SQL modellt: refelhető, tesztelhető, dokumentálható, és megjelenik a lineage grafikonon. Nálam három eset van, amikor pragmatikusan Python modellhez nyúlok: (1) ha valami SQL-ben ronda vagy lehetetlen, például komplex string parsing, JSON deep-extract, gráfszámítás; (2) ha meglévő scikit-learn vagy XGBoost inference pipeline-t kell beépíteni a warehouse-transzformációba; (3) ha a data science csapat már megírta a logikát pandasban, és nem akarok félmilliós SQL-re konvertálni.
Amit NEM ajánlok: egyszerű aggregációkat, joinokat, ablakfüggvényeket Pythonban leírni. A Snowpark vagy Spark motor kevésbé optimalizált a Python DataFrame API-hoz, mint a natív SQL fordítóhoz, és a compute is drágább. Nálam a szabály egyszerű: ha megy SQL-ben olvashatóan, akkor SQL-ben. A Python modell escape hatch, nem alapértelmezés. Ha adattisztításról van szó SQL nélkül, akkor egyébként érdemes megnézni a pandas alapú adattisztítási útmutatót, ami helyi feldolgozásra kiváló. De production pipeline-ban a dbt Python modell azért jobb, mert bekerül a lineage-be és a CI-be.
Milyen adatplatformok támogatják a dbt Python modelleket?
2026 közepén három data platform natívan futtat dbt Python modellt: Snowflake (Snowpark Python), Databricks (PySpark), és BigQuery (BigFrames / Spark stored procedures). A Redshift és Postgres adapterek NEM támogatják, így ha ezeken vagy, a Python modelled nem fog fordulni. Minden platform saját DataFrame típusát preferálja, de a return value szabályai enyhék: Snowparkon Snowpark vagy pandas DataFrame is elfogadott, Databricks-en Spark, pandas vagy pandas-on-Spark, BigQuery-n BigFrames, pandas vagy Spark.
Az alábbi táblázat összefoglalja, mit érdemes 2026-ban tudni a platformkülönbségekről:
Jellemző
Snowflake (Snowpark)
Databricks (PySpark)
BigQuery (BigFrames)
Adapter
dbt-snowflake
dbt-databricks
dbt-bigquery
Preferált DataFrame
Snowpark DataFrame
Spark DataFrame
BigFrames DataFrame
Execution model
Stored procedure a warehouse-ban
Job Databricks clusteren
Serverless Spark
Package management
Snowflake Anaconda channel
pip, Conda, PEX
packages config
Cold start
Alacsony (warehouse-on belül)
Magas (cluster startup)
Közepes
Költségmodell
Warehouse credit
DBU + compute
Slot / on-demand
A saját tapasztalatom: Snowparkon a legalacsonyabb az overhead egy pipeline-runra, mert a Python kód stored procedure-ként fut a meglévő warehouse-ban, cold start szinte nincs. Databrickset akkor válaszd, ha nagy, elosztott PySpark workloadról van szó, és a data engineering csapat már ott dolgozik. A BigQuery BigFrames viszonylag új, én még csak POC szinten láttam production 2026-os deploymentet. Az official dbt Python models dokumentáció minden platformra pontos listát ad az elérhető funkciókról.
Első dbt Python modell Snowparkban lépésről lépésre
Nézzük végig, hogyan írsz egy működő Snowpark Python modellt egy már meglévő dbt projektbe. Feltételezem, hogy van futó dbt-snowflake adaptered (legalább 1.7+, én 1.9-en és a friss Fusion enginen tesztelem), és a profiles.yml-ben a warehouse role-ja rendelkezik USAGE jogosultsággal a Snowpark stored procedure execution-höz.
1. lépés: dependency deklarálás
Hozd létre a models/marts/customer_scoring.py fájlt. Ellentétben az SQL modellel, itt egy model() függvényt írsz, ami két paramétert kap:
import snowflake.snowpark.functions as F
from snowflake.snowpark import DataFrame
def model(dbt, session):
# Konfiguráció: table materializáció, packages import
dbt.config(
materialized="table",
packages=["snowflake-snowpark-python", "pandas"],
)
# Upstream modell referencia (pontosan mint SQL ref())
orders: DataFrame = dbt.ref("stg_orders")
customers: DataFrame = dbt.ref("stg_customers")
# Join Snowpark natív API-val (NEM pandas!)
joined = orders.join(
customers,
orders["customer_id"] == customers["id"],
"inner",
)
# Feature: 30 napos rolling order count
scored = joined.group_by("customer_id").agg(
F.count("order_id").alias("order_count_30d"),
F.sum("amount").alias("total_spend_30d"),
).with_column(
"risk_score",
F.when(F.col("total_spend_30d") < 100, "low")
.when(F.col("total_spend_30d") < 1000, "medium")
.otherwise("high"),
)
return scored
2. lépés: futtatás és validáció
Terminálban futtasd: dbt run --select customer_scoring. A dbt lefordítja a model() függvényt egy Snowflake stored procedure hívássá, feltölti a Snowpark session-t, és a return DataFrame-ből CREATE OR REPLACE TABLE statementet csinál. Első alkalommal 15-30 másodperc a cold start (dependency install), ezután 2-5 másodperc.
3. lépés: dokumentáció és YAML
Írd meg a schema.yml fájlt models/marts/customer_scoring.yml néven, és add hozzá az oszlopokat, teszteket, leírást. A dbt ugyanúgy kezeli, mintha SQL modell lenne. Erről a következő fejezetben részletesen.
Hogyan lehet dbt Python modellt inkrementálisan futtatni?
Az inkrementális Python modellhez a dbt.is_incremental flaggel szűrsz. Amikor True, csak az új sorokat dolgozod fel a dbt.this jelenlegi táblához képest. Ez pontosan ugyanaz a mintázat, mint SQL-ben, csak Python DataFrame API-val írod. Én kizárólag ezt használom mindenre, ami napi több 100 millió sort érint, mert full refresh-re nem futom ki a warehouse budgetet.
Példa egy incremental Python modellre Snowparkon:
import snowflake.snowpark.functions as F
def model(dbt, session):
dbt.config(
materialized="incremental",
unique_key="event_id",
incremental_strategy="merge",
packages=["snowflake-snowpark-python"],
)
events = dbt.ref("stg_events")
if dbt.is_incremental:
# Csak az új események: updated_at > max(updated_at) a jelenlegi táblában
max_updated_query = f"select max(updated_at) as max_ts from {dbt.this}"
max_updated = session.sql(max_updated_query).collect()[0]["MAX_TS"]
events = events.filter(F.col("updated_at") > F.lit(max_updated))
# Nehéz Python logika CSAK a delta soraira fut
enriched = events.with_column(
"session_bucket",
F.when(F.col("session_seconds") < 60, "short")
.when(F.col("session_seconds") < 600, "medium")
.otherwise("long"),
)
return enriched
Fontos backfill tapasztalat: ha módosítod a Python logikát (pl. új bucket határ), akkor kell egy dbt run --select event_enriched --full-refresh a régi partíciók újraszámolásához. Nálam a lecke egy éjszakai 3 órakor jött: a merge stratégia alapból csak az új sorokat frissíti, a régi rossz értékek maradnak. Én ezt CI-ben ellenőrzöm egy dbt-checkpoint hookkal. Ha a model kódja változik, PR templatebe kerül egy „backfill needed?" checkbox.
Python modellek tesztelése dbt-vel
A dbt Python modellek tesztelése ugyanabból a YAML-ből működik, mint az SQL modelleké. A unique, not_null, accepted_values, relationships mind támogatottak, mert dbt a modell output tábláját teszteli, nem a Python kódot magát. Ez az, amiért kompromisszum nélkül tudom mondani a data science csapatnak: „tegyétek dbt Python modelbe, nem lesz kevesebb minőségbiztosítás, mint az SQL-eknél".
Az igazi safety net a saját SQL singular teszt: tests/customer_scoring_no_orphans.sql. Én ide teszem azokat a business ruleket, amiket egy generic teszt nem tud kifejezni:
-- tests/customer_scoring_no_orphans.sql
select cs.customer_id
from {{ ref('customer_scoring') }} cs
left join {{ ref('stg_customers') }} c on cs.customer_id = c.id
where c.id is null
Ha bármelyik sor visszajön, a teszt bukik. Én minden Python modellhez írok legalább egy ilyen tesztet, ami a Python logika egy invariánsát ellenőrzi. A Python „bármit megtehet" szabadsága lehetőség és rizikó egyszerre. További modell-szintű validációhoz érdemes olvasni a scikit-learn Pipeline útmutatót, ami arra fókuszál, hogyan validálod a feature engineering lépéseket a modell training előtt. A két megközelítés kiegészíti egymást.
Teljesítmény optimalizálás dbt Python modellekben
A Python modellek drágábban futnak, mint az SQL-ek, mert general-purpose compute-on hajtódnak végre a warehouse dedicated SQL enginje helyett. 2026-ban van négy szabály, amit kőbe véstem magamnak, és amit minden PR review-n bekérek a csapattól.
1. Natív DataFrame API, nem pandas
Snowparkon a .filter(), .select(), .join() hívások a warehouse execution engine-re fordulnak, tehát pontosan olyan gyorsan futnak, mint az SQL. Amint .to_pandas()-t hívsz, a teljes DataFrame a Python worker RAM-jába kerül, és a maradék logika ott fut soronként. Egy 200 millió soros táblán ez OOM-ot okoz, garantáltan.
2. Szűrj korán, join-olj feljebb
Ha 500M sort olvasol be, majd Pythonban szűröd le 5M-re, akkor 495M sor felesleges I/O-t fizetsz. Vagy tegyél egy upstream SQL modellt ref()-fel, ami már leszűrve adja a bemenetet, vagy hívj .filter()-t a Snowpark API-ban a legelső lépésként.
3. Inkrementális, ahol lehet
Ha a modell változatlan bemenetre determinisztikus, nagyon valószínű, hogy inkrementálisan kell futtatnod. Full refresh-t csak akkor, ha a Python kód logikája változik.
4. Vektorizáció, nem row-by-row apply
A df.apply(lambda row: ...) pandasban is lassú, de Snowparkon vagy Sparkon egyenesen katasztrófa, mert minden row Python function callon megy át, JIT nincs. Használj vectorized UDF-et (Snowparkon @F.udf(vectorized=True)) vagy natív oszlop kifejezéseket. Aki nagyobb dataframe teljesítményről akar többet olvasni Python oldalról, annak érdemes megnézni a Pandasról Polarsra migrációs útmutatót, mert a lazy evaluation koncepció Snowpark és PySpark alatt is ugyanúgy működik.
Gyakori hibák és pipeline-t leállító tipikus footgunok
Három éve gyűjtöm a listát a dbt Python modellel kapcsolatos „miért nem működik" incidensekről. Itt az öt leggyakoribb, amit tapasztalatból tudok, és amikkel 3 óra debug megspórolható.
Csak table vagy incremental materializáció megengedett
Ha materialized='view' vagy 'ephemeral' beállítást teszel egy Python modellbe, a dbt parse lépés nem hibázik, de a dbt run igen, cryptic error message-dzsel. Csak table vagy incremental.
A dbt.ref() DataFrame-et ad vissza, NEM Snowpark table nevet
Sok új user próbál session.table(dbt.ref("stg_orders"))-t hívni. Nem működik. A dbt.ref() már a session-hoz kötött DataFrame-et adja vissza; csak add hozzá a további DataFrame API hívásokat.
Package version mismatch Snowflake Anaconda channelen
Snowflake csak egy előre curated Anaconda package listát támogat Snowparkon. Ha packages=["torch==2.5.0"]-t teszel a config-ba, és a Snowflake channel csak 2.3.0-t támogat, akkor futásidőben hibázik. Mindig ellenőrizd a Snowflake Anaconda channelt a támogatott verziókért.
Stored procedure execution timeout
Snowparkon a stored procedure hívásoknak default 1 órás timeoutja van. Ha 500M soros incrementált akarsz teljesíteni, és pandasra konvertálsz, könnyen timeoutba futsz. Vagy inkrementálisan futtass, vagy növeld a warehouse méretét. Én még soha nem volt szükségem 1 óránál hosszabb Python model futásra, ha jól bontottam a lépéseket.
CI/CD kompatibilitás dbt Fusion-nel
A dbt Labs 2025-ben kiadta a dbt Fusion enginet (Rust alapú), ami a Python modelleket kicsit másképp kezeli. Bizonyos packages config forma és az adapter selection eltér. Ha még dbt Core 1.7-en vagy, és Fusion-re akarsz frissíteni, olvasd el a dbt Labs hivatalos Python + Snowpark lab-jét, ami már Fusion-kompatibilis példákkal jön.
Gyakran ismételt kérdések
Snowpark vagy pandas DataFrame-et használjak dbt Python modellben?
Snowparkot preferáld, mert a natív DataFrame API a Snowflake execution engine-en fut, nem a Python worker RAM-jában. Csak akkor konvertálj pandasra (.to_pandas()), ha kifejezetten olyan library-t használsz (scikit-learn, XGBoost inference), ami pandast igényel. És akkor is limitáld a sorok számát legfeljebb néhány millióra.
Mi a különbség dbt SQL model és dbt Python model között?
Az SQL modell Jinja-templatelt SELECT statement, amit dbt egy CREATE TABLE AS-re fordít. A Python modell egy model(dbt, session) függvény, ami DataFrame-et ad vissza; dbt stored procedure-ként (Snowflake) vagy Spark jobként (Databricks) futtatja. A dbt lineage, tesztelés, dokumentáció mindkettőre ugyanúgy működik, de a Python drágább compute-tal fut, és csak table/incremental materializációt támogat.
Mennyibe kerül egy dbt Python modell futtatása Snowflake-en?
A pontos költség a warehouse méretétől és futásidőtől függ. Tapasztalatom szerint egy közepes complexity Python modell 2-5x annyi warehouse credit-et fogyaszt, mint ugyanaz a logika SQL-ben. Ezért én mindig SQL-re optimalizálom a joinokat és aggregációkat, és a Python modellben csak a valóban Python-only logika marad (ML inference, komplex string parse).
Támogatja a dbt Core a Python modelleket, vagy csak a dbt Cloud?
Mindkettő. A dbt Core (open source, ingyenes) 1.3-tól támogatja a Python modelleket a dbt-snowflake, dbt-databricks, dbt-bigquery adapterek segítségével. A dbt Cloud ugyanazokat az adaptereket használja, plusz IDE-t, scheduler-t és observabilityt ad hozzá. A Python modell szintaxis és a végrehajtás modellje azonos.
Hogyan tesztelhető lokálisan egy dbt Python modell?
A Python model kód warehouse-on fut, tehát nem tudod lokálisan „futtatni" úgy, mint egy sima Python scriptet. De: a model() függvényt kiszervezheted egy külön Python fájlba (pl. helpers/scoring.py), unit teszttel lefeded pytesttel egy dummy DataFrame-en, majd a modelben csak importálod. Így a business logika unit tesztelt, a dbt run pedig integration tesztként validál end-to-end.