Arquitectura de datos cloud
Cloud

dbt en 2025: el estándar del Data Warehouse moderno

Por Antonio Moro1 Feb 20259 min lectura

En 2025, si construyes un Data Warehouse sin dbt, estás eligiendo el camino difícil. dbt (data build tool) ha ganado el mercado de transformaciones ELT de forma aplastante. No porque sea perfecto, sino porque resuelve un problema real que cualquier equipo de datos ha sufrido: cómo gestionar transformaciones SQL de forma profesional, versionada y probada.

Por qué dbt ha ganado el mercado

Antes de dbt, el flujo típico era: un analista escribía SQL en un editor, lo pegaba en el DWH, y nadie sabía de dónde venían los datos ni quién los había transformado. dbt cambió esto introduciendo:

“dbt les da a los ingenieros de datos las mejores prácticas de ingeniería de software: tests, documentación, modularidad y control de versiones. Todo aplicado a SQL.”

dbt Core vs dbt Cloud

Característicadbt Coredbt Cloud
PrecioGratuito (open source)Desde 50 USD/usuario/mes
InterfazCLI únicamenteIDE web + CLI
OrquestaciónManual / AirflowJobs gestionados
Alertas y monitoreoNo incluidoIncluido
CI/CD integradoRequiere configuraciónNativo (GitHub/GitLab)
Mejor paraEquipos pequeños, experimentaciónEquipos medianos/grandes

Arquitectura de un proyecto dbt

mi_proyecto_dbt/
|-- dbt_project.yml        # configuracion del proyecto
|-- profiles.yml           # conexion al DWH (fuera del repo)
|-- models/
|   |-- staging/           # fuentes en bruto, 1:1 con tablas origen
|   |   |-- stg_ventas.sql
|   |   |-- stg_clientes.sql
|   |   |-- _sources.yml   # definicion de fuentes
|   |-- intermediate/      # calculos intermedios, no expuestos
|   |   |-- int_ventas_enriquecidas.sql
|   |-- marts/             # tablas finales para BI
|   |   |-- ventas/
|   |   |   |-- fct_ventas.sql
|   |   |   |-- dim_cliente.sql
|   |   |   |-- _schema.yml  # tests y documentacion
|-- seeds/                 # CSVs estaticos
|-- macros/                # funciones SQL reutilizables
|-- tests/                 # tests singulares (SQL custom)
|-- snapshots/             # SCD tipo 2 (historial de cambios)

Ejemplo de modelo con Jinja

-- models/staging/stg_ventas.sql
{{ config(materialized='view') }}

WITH source AS (
    SELECT * FROM {{ source('raw', 'ventas') }}
),

renamed AS (
    SELECT
        CAST(id_venta AS STRING)         AS venta_id,
        CAST(id_cliente AS STRING)       AS cliente_id,
        CAST(id_producto AS STRING)      AS producto_id,
        DATE(fecha_venta)                AS fecha_venta,
        CAST(cantidad AS INT64)          AS cantidad,
        CAST(precio_unitario AS FLOAT64) AS precio_unitario,
        CAST(descuento AS FLOAT64)       AS descuento,
        cantidad * precio_unitario * (1 - descuento) AS importe_neto,
        _PARTITIONDATE                   AS fecha_carga
    FROM source
    WHERE fecha_venta IS NOT NULL
      AND cantidad > 0
)

SELECT * FROM renamed

Tests genéricos en schema.yml

# models/marts/ventas/_schema.yml
version: 2

models:
  - name: fct_ventas
    description: "Tabla de hechos de ventas. Una fila por linea de pedido."
    columns:
      - name: venta_id
        tests:
          - unique
          - not_null
      - name: cliente_id
        tests:
          - not_null
          - relationships:
              to: ref('dim_cliente')
              field: cliente_id
      - name: importe_neto
        tests:
          - not_null
          - dbt_utils.accepted_range:
              min_value: 0

Despliegue en GCP BigQuery (paso a paso)

# 1. Instalar dbt con el adaptador de BigQuery
pip install dbt-bigquery

# 2. Configurar profiles.yml (~/.dbt/profiles.yml)
my_project:
  target: dev
  outputs:
    dev:
      type: bigquery
      method: oauth
      project: mi-proyecto-gcp
      dataset: dbt_dev
      threads: 4
    prod:
      type: bigquery
      method: service-account
      project: mi-proyecto-gcp
      dataset: dbt_prod
      keyfile: /path/to/service-account.json
      threads: 8

# 3. Verificar conexion
dbt debug

# 4. Ejecutar todos los modelos
dbt run

# 5. Ejecutar tests
dbt test

# 6. Generar documentacion
dbt docs generate
dbt docs serve

Despliegue en Azure Synapse / Azure SQL

# 1. Instalar adaptador de Synapse
pip install dbt-synapse

# 2. Configurar profiles.yml para Synapse
my_project:
  target: dev
  outputs:
    dev:
      type: synapse
      driver: 'ODBC Driver 18 for SQL Server'
      server: mi-workspace.sql.azuresynapse.net
      port: 1433
      database: mi_dedicated_pool
      schema: dbt_dev
      authentication: ServicePrincipal
      tenant_id: "xxxx-xxxx-xxxx"
      client_id: "xxxx-xxxx-xxxx"
      client_secret: "{{ env_var('DBT_AZURE_CLIENT_SECRET') }}"
      threads: 4

# 3. Ejecutar solo modelos de staging
dbt run --select staging

# 4. Ejecutar con full-refresh (reconstruir desde cero)
dbt run --full-refresh

Integración con Apache Airflow

from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime

with DAG(
    dag_id='dbt_daily_run',
    schedule_interval='0 6 * * *',
    start_date=datetime(2025, 1, 1),
    catchup=False,
    tags=['dbt', 'datawarehouse']
) as dag:

    dbt_run = BashOperator(
        task_id='dbt_run',
        bash_command='cd /opt/dbt/mi_proyecto && dbt run --target prod',
        env={'DBT_PROFILES_DIR': '/opt/dbt/profiles'}
    )

    dbt_test = BashOperator(
        task_id='dbt_test',
        bash_command='cd /opt/dbt/mi_proyecto && dbt test --target prod'
    )

    dbt_run >> dbt_test
Buena práctica

Usa el proveedor oficial apache-airflow-providers-dbt-cloud si usas dbt Cloud. Para dbt Core, el BashOperator es la opción más portable. El paquete astronomer-cosmos convierte cada modelo dbt en una tarea Airflow individual para mayor observabilidad.


dbt Starter Kit para BigQuery y Snowflake

Proyecto dbt completo con estructura de carpetas, modelos de staging y marts, tests genéricos preconfigurados, macros de utilidad y documentación. Listo para arrancar en horas, no semanas.

Ver recursos →