dbt con Python
dbt gestiona las transformaciones del almacén de datos como modelos versionados, principalmente en SQL, con modelos de Python donde los adaptadores permiten lógica estilo pandas/polars en el tiempo de ejecución del almacén.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
# models/staging/stg_orders.sql
select
order_id,
cast(revenue as double) as revenue,
region,
ordered_at
from {{ source('raw', 'orders') }}
where order_id is not null# models/marts/revenue_by_region.py (modelo Python de dbt)
def model(dbt, session):
df = dbt.ref("stg_orders").to_pandas()
return df.groupby("region", observed=True)["revenue"].sum().reset_index()Cuándo usar esto:
- Transformaciones analíticas propiedad de los equipos de datos en SQL
- Necesidad de pruebas, documentación y linaje en tablas del almacén de datos
- Python solo para características estadísticas/ML que SQL no puede expresar limpiamente
- CI ejecuta
dbt builden cada PR
Ejemplo de Trabajo
-- models/staging/stg_orders.sql
with source as (
select * from {{ source('ecommerce', 'orders') }}
),
cleaned as (
select
order_id,
upper(trim(region)) as region,
cast(revenue as numeric(18, 2)) as revenue,
ordered_at::timestamp_tz as ordered_at
from source
where revenue >= 0
)
select * from cleaned# models/staging/schema.yml
models:
- name: stg_orders
columns:
- name: order_id
tests: [unique, not_null]
- name: revenue
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0-- models/marts/fct_revenue_daily.sql
select
date_trunc('day', ordered_at) as revenue_date,
region,
sum(revenue) as total_revenue,
count(*) as order_count
from {{ ref('stg_orders') }}
group by 1, 2Lo que esto demuestra:
- Grafo de dependencias
sourceyref - Limpieza de staging en SQL cerca del motor del almacén de datos
- Pruebas YAML en claves y límites de ingresos
- Agregación de mart como modelo descendente
Profundización
Cómo Funciona
- dbt compila Jinja SQL, ejecuta materializaciones (
view,table,incremental). - DAG desde
ref()-dbt buildejecuta pruebas después de construir modelos. - Los modelos de Python delegan al tiempo de ejecución del adaptador (Snowflake Snowpark, BigQuery, etc.).
- Artefactos:
manifest.json,catalog.jsonpara herramientas de linaje.
Estratificación
| Capa | Rol |
|---|---|
| staging | Renombrar, castear, limpieza ligera |
| intermediate | Uniones de negocio |
| marts | Hechos/dimensiones orientados al consumidor |
Notas de Python
# Mantén los modelos de Python delgados - la mayor parte del trabajo pesado todavía pertenece a SQL cuando es posible
def model(dbt, session):
import pandas as pd
orders = dbt.ref("stg_orders")
pdf = orders.to_pandas() if hasattr(orders, "to_pandas") else orders
# ingeniería de características...
return pdfErrores Comunes
- Modelo Python en adaptador incorrecto - no todos los almacenes de datos soportan modelos de Python. Solución: consultar la documentación del adaptador; recurrir a UDF de SQL.
- Lógica duplicada en herramientas de BI - las métricas divergen de los marts de dbt. Solución: exponer los granos en los marts; la BI solo visualiza.
- Omitir pruebas en staging - las claves incorrectas se propagan. Solución:
unique/not_nullcomo mínimo en las claves primarias. - Refresco completo incremental por error - reconstrucción costosa. Solución: documentar
incremental_strategyy claves únicas. - Nombres de base de datos codificados - falla entre entornos. Solución: los perfiles
targetde desarrollo/producción a través de variables de entorno.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Stored procs SQL puras | Equipo de operaciones nativo del almacén | Quieres flujo de trabajo de PR de git y pruebas |
| Scripts de pandas | Transformaciones a escala de portátil | El almacén de datos es la fuente de verdad |
| Spark/dbt-spark | Transformaciones de clústeres enormes | Los marts SQL son suficientes |
| SQLMesh | Necesitas entornos virtuales por rama | El equipo ya usa dbt Cloud |
Preguntas Frecuentes
¿Modelos SQL o Python?
- SQL por defecto - el almacén de datos optimiza las uniones y agregaciones.
- Python para características estilo sklearn que los adaptadores soportan.
¿Cómo ejecuto localmente?
dbt debug && dbt build --select stg_orders+¿Qué es incremental?
- Añade/fusiona solo particiones nuevas.
- Requiere una clave única y una guarda
is_incremental()en el modelo.
¿Cómo documento columnas?
- Los campos
descriptiondeschema.ymlse reflejan en el sitio de documentación de dbt.
¿Puede dbt leer Parquet en S3?
- A través de tablas externas en Snowflake/BigQuery/DuckDB adapters.
- El patrón varía según el almacén de datos - no es solo dbt core genérico.
¿Cómo pruebo relaciones?
tests:
- relationships:
to: ref('dim_customers')
field: customer_id¿CI con dbt Cloud o CLI?
- CLI en GitHub Actions es común para control de costos.
- Cloud añade planificador e IDE - preferencia del equipo.
¿Qué importancia tiene Python 3.14?
- Las invocaciones locales de dbt usan tu Python; los tiempos de ejecución del adaptador usan las versiones de Python del almacén de datos.
- Fija dbt-core local con archivos de bloqueo
uv.
¿Cómo manejo información personal identificable (PII)?
- Hashear/enmascarar en staging; etiquetar modelos como
piien metadatos YAML.
¿Monorepo con código de aplicación?
models/vive junto a la aplicación - trabajo de CI separado paradbt build.
Relacionado
- Validación y Calidad de Datos - pruebas de expectativas
- Formatos de Archivo - tablas externas en Parquet
- Fundamentos de Ingeniería de Datos - ciclo de vida ETL
- PySpark - alternativa a escala de clúster
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.