dbt vs Lakeflow Declarative Pipelines
Objetivo: decidir cuándo utilizar dbt, cuándo Lakeflow y cómo combinarlos en una Data Platform con Azure Event Hubs, Delta Lake, Unity Catalog y Power BI.
1. La diferencia fundamental
Lakeflow Declarative Pipelines
Motor declarativo integrado en Databricks para construir pipelines batch y streaming.
Destaca en ingesta, streaming, CDC y procesamiento incremental gestionado.
dbt
Framework de transformación de datos orientado a modelos, SQL, testing, documentación y reutilización.
Destaca en modelado analítico y transformación SQL mantenible.
Ambos permiten crear dependencias entre transformaciones y desplegarlas mediante CI/CD, pero no delegan las mismas responsabilidades al framework.
Lakeflow gestiona el procesamiento de streaming y puede mantener Materialized Views incrementalmente. dbt ofrece mecanismos para definir cómo se materializan y actualizan modelos sobre el motor de datos utilizado, en nuestro caso Databricks.
Databricks on Google Cloud+1
2. Comparación técnica
Capacidad | Lakeflow | dbt |
|---|---|---|
SQL | ||
Python / PySpark | Soporte de Python, con restricciones | |
Kafka / Event Hubs | Streaming nativo | No es un consumidor Kafka |
Streaming continuo | Orientado a ejecuciones | |
Incremental refresh | Automático para MVs compatibles | Configurado por modelo |
CDC / SCD2 | AUTO CDC | Snapshots / lógica SQL |
Data Quality | Expectations | Data tests |
Documentación de modelos | Integrada con el ecosistema | Especialmente completa |
Portabilidad entre motores | Centrado en Databricks/Spark | Múltiples adaptadores |
Integración Unity Catalog | Nativa | Mediante adaptador Databricks |
La diferencia más interesante no es Python frente a SQL, porque Lakeflow soporta ambos lenguajes. Es quién controla el procesamiento incremental y cuánto trabajo tienes que implementar.
3. Modelos incrementales: el mismo KPI en ambos
Supongamos que queremos calcular ventas mensuales por farmacia.
A. Lakeflow: Materialized View
@dp.materialized_view(name="gold_monthly_sales")
def gold_monthly_sales():
return spark.sql("""
SELECT
pharmacy_id,
DATE_TRUNC('MONTH', event_time) AS month,
SUM(amount) AS sales
FROM silver_tickets
GROUP BY 1, 2
""")Lakeflow analiza los cambios de las fuentes e intenta aplicar incremental refresh cuando es viable.
No defines un MERGE ni un filtro incremental manual. Databricks on Google Cloud
B. dbt: modelo incremental
models/gold_monthly_sales.sql
{{
config(
materialized='incremental',
incremental_strategy='merge',
unique_key=['pharmacy_id', 'month']
)
}}
SELECT
pharmacy_id,
DATE_TRUNC('MONTH', event_time) AS month,
SUM(amount) AS sales
FROM {{ ref('silver_tickets') }}
{% if is_incremental() %}
WHERE updated_at >= (
SELECT COALESCE(
MAX(last_updated_at),
TIMESTAMP '1900-01-01'
)
FROM {{ this }}
)
{% endif %}
GROUP BY 1, 2
Este segundo fragmento es ilustrativo, no un modelo completo listo para ejecutar: habría que proyectar y mantener last_updated_at y definir correctamente la detección de cambios.
Además, existe un problema más profundo.
¿Lo ves?
Si solo seleccionamos tickets modificados, SUM(amount) calcula el importe de esos tickets, no el total del mes.
Un MERGE con ese resultado podría sobrescribir incorrectamente el KPI.
Por ejemplo:
Agosto tiene ventas por 100.000 €.
Se corrige un ticket de 100 € a 80 €.
El modelo recibe únicamente ese ticket.
Si hace
MERGEsustituyendosales, podría escribir 80 € en lugar del total correcto de agosto.
Esto es uno de los principales errores al implementar agregaciones incrementales en dbt.
dbt Developer Hub4. Cómo resolver correctamente KPIs históricos con dbt
En la lección 16 aprendimos que Delta CDF nos permite identificar los períodos afectados por una corrección.
Podemos utilizar exactamente esa idea con dbt.
Delta CDF
Ticket de agosto modificado en noviembreIdentificar períodos afectados
Agosto 2026dbt incremental model
Recalcular agosto completo desde SilverMERGE en Gold
Actualizar únicamente los períodos afectadosEjemplo de modelo dbt, suponiendo que un proceso anterior ha preparado changed_months con todos los meses afectados:
{{
config(
materialized='incremental',
incremental_strategy='merge',
unique_key=['pharmacy_id', 'month']
)
}}
SELECT
pharmacy_id,
DATE_TRUNC('MONTH', event_time) AS month,
SUM(amount) AS sales
FROM {{ ref('silver_tickets') }}
{% if is_incremental() %}
WHERE DATE_TRUNC('MONTH', event_time) IN (
SELECT DISTINCT month
FROM {{ ref('changed_months') }}
)
{% endif %}
GROUP BY 1, 2
Esto sí recalcula las ventas completas de los meses afectados, en lugar de sumar únicamente las filas modificadas.
Hay tres condiciones que debemos resolver para convertirlo en producción:
changed_monthsdebe incluir tanto los períodos antiguos como los nuevos cuando cambien fechas.Los cambios deben procesarse con un control persistente del progreso, sin perderlos en caso de fallo.
Si una eliminación deja un mes sin registros, un
MERGEconvencional no elimina automáticamente la fila obsoleta. Necesitamos gestionar ese caso expresamente.
En dbt también existen estrategias como insert_overwrite y microbatch, sujetas a la compatibilidad del adaptador, que merece la pena evaluar para datos particionados temporalmente.
dbt Developer Hub+1
La comparación importante: con Lakeflow MV comenzamos declarando el resultado y dejamos que el optimizador intente actualizarlo incrementalmente. En dbt incremental tenemos mayor control explícito, pero también más responsabilidad de asegurar que el resultado sea correcto.
5. CDC y Snapshots: ¿son equivalentes?
No exactamente.
Lakeflow AUTO CDC procesa eventos de cambio y puede mantener una tabla SCD Type 2 incluso cuando los eventos llegan desordenados.
dbt Snapshots observa el estado de una tabla en distintas ejecuciones y guarda sus versiones.
Ejemplo de snapshot dbt:
snapshots/customers.yml
snapshots:
- name: customers_history
relation: ref('silver_customers')
config:
strategy: timestamp
unique_key: customer_id
updated_at: updated_at
El resultado tendrá columnas como:
customer_id
city
dbt_valid_from
dbt_valid_toHay una diferencia crítica: si un cliente cambia tres veces entre dos ejecuciones de dbt Snapshot, podemos perder los estados intermedios.
Con AUTO CDC, si recibimos los tres eventos, podemos conservar las tres versiones en SCD2.
Por eso, para una fuente de eventos CDC reales, preferiría AUTO CDC. Los snapshots dbt tienen mucho sentido cuando la fuente solo expone su estado actual.
dbt Developer Hub+1
6. Data Quality: Expectations vs dbt Tests
Lakeflow Expectations
@dp.expect_or_drop(
"valid_id",
"ticket_id IS NOT NULL"
)
Validación integrada en el flujo de procesamiento.
Warn · Drop · Faildbt Tests
models:
- name: silver_tickets
columns:
- name: ticket_id
data_tests:
- not_null
- unique
Consultas de validación sobre el resultado de los modelos.
Pass · Warn · ErrorAmbos permiten reglas personalizadas.
La diferencia es que expect_or_drop puede excluir directamente un registro durante la transformación. Un test de dbt normalmente comprueba los datos y comunica si cumplen las reglas; no elimina automáticamente las filas inválidas.
dbt proporciona de serie tests de unicidad, nulos, relaciones y valores aceptados. También permite documentar modelos, columnas y sus dependencias. dbt Developer Hub
No los trataría como sustitutos perfectos: usaría Expectations para controles de ingesta y dbt Tests para validar integridad y reglas analíticas cuando esos modelos estén gestionados por dbt.
7. ¿Y Python?
Aquí es donde suele haber confusión.
dbt también soporta modelos Python, incluidos algunos incrementales, dependiendo del adaptador.
Sin embargo, tienen restricciones de materialización y ejecución. No equivalen a un pipeline PySpark Structured Streaming con soporte nativo de Kafka, watermarks y checkpoints. dbt Developer Hub
Trabajo | Preferencia |
|---|---|
Leer Event Hubs | Lakeflow |
Deserializar Avro | Lakeflow + Python |
CDC complejo | Lakeflow AUTO CDC |
Transformaciones SQL analíticas | dbt o Lakeflow SQL |
Tests de modelos semánticos | dbt |
Transformaciones streaming con estado | Lakeflow |
8. Comparación de costes
Ninguna de las dos herramientas es necesariamente más barata.
La comparación real debe considerar qué motor ejecuta las consultas, qué datos procesa y cuánto trabajo se repite.
Situación | Posible ventaja |
|---|---|
Ingesta continua de eventos | Lakeflow |
Agregación con incremental refresh eficiente | Lakeflow MV |
Transformación SQL sencilla cada hora | dbt puede ser competitivo |
Recálculo controlado de particiones | dbt incremental |
SQL complejo que obliga a Full Recompute | Depende del volumen y diseño |
Además, dbt Core no requiere una licencia de suscripción, pero las consultas ejecutadas en Databricks sí consumen recursos. dbt también ofrece productos comerciales con sus propios costes.
Databricks permite ejecutar dbt Core como una tarea de Lakeflow Jobs, utilizando un SQL Warehouse. Por tanto, no necesitamos otra plataforma de orquestación obligatoriamente. Databricks on AWS
9. Mi arquitectura propuesta para vuestra Data Platform
La arquitectura híbrida que evaluaría inicialmente sería:
Azure Event Hubs
Eventos de tickets, clientes y trackingBronze
Ingesta · Avro raw · CheckpointsSilver
Deserialización · Expectations · AUTO CDCGold incremental
Agregaciones compatibles y eficientesGold analítico
Modelos SQL, tests y lógica de negocioPower BI / Data Products
Tablas gobernadas en Unity CatalogNo duplicaría KPIs entre Lakeflow y dbt. Definiría un único propietario por modelo y una interfaz de datos bien establecida.
Cómo decidiría qué va en Gold
Explora cuatro decisiones habituales
Evaluaría dbt
La estructura de modelos, macros, tests y documentación puede facilitar que varios equipos mantengan la lógica. Debemos medir el coste de las materializaciones.
10. Mini ejercicio final
Tenemos que desarrollar una plataforma con estas necesidades:
Eventos Avro desde Kafka.
Perfiles de clientes que cambian.
KPIs mensuales con correcciones históricas.
Modelos analíticos SQL documentados y validados.
¿Qué diseño elegirías?
Curso completado: 17 lecciones
Lakeflow Declarative Pipelines
17 / 17Has recorrido los fundamentos, streaming, CDC, CDF, incremental refresh, observabilidad, producción y comparación con dbt.
Siguiente paso que te recomiendo
Antes de adoptar dbt o migrar los pipelines actuales a Lakeflow, haría una PoC comparativa sobre un único KPI real.
Utilizaría un conjunto de tickets con correcciones retroactivas y mediría tres implementaciones: Lakeflow MV, dbt incremental con recálculo de períodos afectados y PySpark/Delta MERGE manual.
Compararía la corrección funcional del resultado, la duración p95 de las actualizaciones, DBUs consumidos y esfuerzo de mantenimiento.
Una idea más en tu cuaderno.
Marca esta lección cuando hayas terminado de repasarla.
Material importado del curso original. Simulaciones conservadas como ejemplos estáticos; para sus controles interactivos, consulta el original.