Cómo Instalar y Configurar dbt Core con BigQuery desde CERO
En este tutorial de dbt BigQuery en español vamos a construir una base profesional de Analytics Engineering: instalación de dbt Core, configuración de credenciales, ejecución de dbt init, conexión con BigQuery y creación de los primeros staging models. El objetivo no es simplemente conseguir que dbt funcione, sino entender cómo diseñar un proyecto que pueda crecer sin convertirse en deuda técnica.
Lo que aprenderás
La instalación es solamente el primer paso. La parte importante es comprender dónde colocar cada responsabilidad para que el proyecto pueda evolucionar desde un laboratorio hasta un entorno empresarial.
Stack tecnológico
El tutorial utiliza un stack deliberadamente sencillo: Python para el runtime de dbt, BigQuery como plataforma analítica y SQL/Jinja como lenguaje de transformación.
El modelo mental correcto: dbt no es un motor de datos
Una de las confusiones más habituales al comenzar con dbt es pensar que dbt sustituye al data warehouse. No lo hace. BigQuery ejecuta el trabajo pesado; dbt organiza, versiona, prueba y documenta la lógica de transformación.
La arquitectura recomendada separa el dato físico de la lógica de transformación. BigQuery almacena y procesa los datos, mientras que dbt actúa como una capa de ingeniería que convierte SQL disperso en un proyecto versionado y gobernado.
Esta separación es especialmente importante cuando varios equipos trabajan sobre el mismo warehouse: el objetivo deja de ser simplemente "hacer una consulta que funcione" y pasa a ser crear transformaciones reproducibles, observables y mantenibles.
Matriz de decisión arquitectónica
dbt y BigQuery resuelven problemas diferentes. La siguiente matriz ayuda a ubicar cada componente dentro de una arquitectura analítica moderna.
| Componente | Responsabilidad | Latencia típica | Consistencia | Coste | Uso recomendado |
|---|---|---|---|---|---|
| BigQuery | Almacenamiento y ejecución SQL analítica. | Segundos a minutos | Alta | Variable según almacenamiento y computación | OLAP, analytics, reporting, ML y transformaciones. |
| dbt Core | Orquestación lógica de transformaciones SQL, tests y documentación. | Depende del warehouse | Determinada por el warehouse y el DAG | Bajo runtime; coste principal en infraestructura subyacente | Analytics Engineering y transformación ELT. |
| OLTP | Transacciones operacionales. | Milisegundos | Fuerte según el sistema | Variable | Aplicaciones, operaciones y sistemas transaccionales. |
| Staging | Normalización inicial y contrato técnico de las fuentes. | Depende de la materialización | Alta si se aplican tests y contratos | Variable | Limpiar nombres, tipos, timestamps y campos fuente. |
| Marts | Modelo orientado al negocio. | Depende del DAG | Alta mediante tests | Variable | BI, métricas, reporting y consumo analítico. |
Instalar dbt Core con BigQuery
La instalación profesional debería aislar las dependencias de Python. Un entorno virtual evita que versiones de otros proyectos contaminen el runtime de dbt.
# Crear el directorio del proyecto
mkdir dbt-bigquery-tutorial
cd dbt-bigquery-tutorial
# Crear un entorno virtual
python -m venv .venv
# Activarlo en Linux/macOS
source .venv/bin/activate
# Windows PowerShell:
# .\.venv\Scripts\Activate.ps1
# Actualizar pip
python -m pip install --upgrade pip
# Instalar dbt Core + adaptador BigQuery
python -m pip install dbt-core dbt-bigquery
# Verificar la instalación
dbt --version
¿Por qué instalar el adaptador?
dbt-core contiene el framework principal, mientras que dbt-bigquery proporciona la integración específica con BigQuery. Separar ambos conceptos es importante porque dbt soporta diferentes data warehouses mediante adaptadores.
dbt init: crear el proyecto desde cero
Una vez instalado dbt, dbt init genera la estructura inicial del proyecto y permite seleccionar la configuración del adaptador.
dbt init analytics_platform
Estructura inicial recomendada
analytics_platform/
├── dbt_project.yml
├── models/
│ ├── staging/
│ │ ├── sources.yml
│ │ └── stg_customers.sql
│ ├── intermediate/
│ └── marts/
├── macros/
├── seeds/
├── snapshots/
├── tests/
└── analyses/
Configurar profiles.yml correctamente
profiles.yml conecta el proyecto dbt con el target de ejecución. En entornos reales, las credenciales no deberían formar parte del repositorio.
analytics_platform:
target: dev
outputs:
dev:
type: bigquery
method: oauth
project: "TU_PROJECT_ID"
dataset: "analytics_dev"
threads: 4
location: "EU"
prod:
type: bigquery
method: oauth
project: "TU_PROJECT_ID"
dataset: "analytics_prod"
threads: 8
location: "EU"
La decisión arquitectónica importante
Observa que dev y prod no apuntan necesariamente al mismo dataset. Esta separación evita que una ejecución experimental destruya o modifique modelos productivos.
En equipos empresariales, el patrón puede evolucionar hacia proyectos de Google Cloud separados para desarrollo, staging y producción, con identidades y permisos diferenciados. El objetivo es aplicar el principio de least privilege y limitar el blast radius de cualquier ejecución incorrecta.
Validar la conexión antes de escribir modelos
No empieces creando veinte modelos SQL para descubrir después que el problema era una credencial, un proyecto incorrecto o una región incompatible.
# Desde el directorio raíz del proyecto
dbt debug
# Inspeccionar los modelos disponibles
dbt ls
# Ejecutar el proyecto
dbt run
Orden de diagnóstico
Si dbt debug falla, no intentes resolverlo modificando los modelos. Primero verifica identidad, proyecto, método de autenticación, dataset, región y permisos. Separar problemas de infraestructura de problemas de transformación reduce muchísimo el tiempo de troubleshooting.
Staging models: la primera capa realmente importante
Un staging model no debería convertirse en un lugar para implementar toda la lógica de negocio. Su función principal es establecer una interfaz limpia entre las fuentes y el resto del DAG.
{{
config(
materialized='view'
)
}}
with source as (
select *
from {{ source('raw', 'customers') }}
),
renamed as (
select
cast(customer_id as int64) as customer_id,
cast(email as string) as email,
cast(first_name as string) as first_name,
cast(last_name as string) as last_name,
timestamp(created_at) as created_at,
timestamp(updated_at) as updated_at
from source
)
select *
from renamed
version: 2
sources:
- name: raw
schema: raw
tables:
- name: customers
description: "Clientes procedentes del sistema operacional."
columns:
- name: customer_id
description: "Identificador único del cliente."
tests:
- not_null
- unique
- name: email
description: "Email del cliente."
Antipatrones críticos: lo que no debes hacer
Muchos proyectos dbt funcionan perfectamente durante los primeros meses y empiezan a fallar cuando aumenta el volumen, el número de desarrolladores o la frecuencia de ejecución.
⚠ Error: convertir staging en una capa de negocio
Un staging model debería encargarse principalmente de normalización técnica: nombres, tipos de datos, campos, timestamps y pequeñas transformaciones directamente relacionadas con la fuente.
Introducir aquí joins complejos, reglas de negocio, segmentaciones comerciales y métricas finales genera un acoplamiento peligroso entre la fuente y el dominio.
- La lógica de negocio se vuelve difícil de reutilizar.
- Los cambios en una fuente producen efectos secundarios inesperados.
- Los modelos downstream dejan de tener una responsabilidad clara.
- El DAG crece horizontalmente sin una arquitectura comprensible.
Solución: mantener staging pequeño y determinista, mover lógica compleja a intermediate y presentar entidades orientadas al negocio en marts.
FinOps: el error que puede multiplicar la factura
dbt no elimina el coste de BigQuery. Cada materialización y cada consulta que ejecuta dbt puede consumir recursos del warehouse. Por eso la arquitectura del DAG también es una decisión económica.
Evita SELECT *
En staging puede ser útil durante exploración, pero los modelos persistentes deberían seleccionar explícitamente las columnas necesarias.
Materializa con intención
No conviertas todo en tablas físicas. Utiliza views, tables o incremental según el patrón de acceso, volumen y frecuencia de actualización.
Controla el volumen
Filtrar particiones, limitar columnas y diseñar incremental models correctamente puede tener más impacto económico que microoptimizar SQL.
Implementación de producción: staging incremental
Cuando el volumen crece, una estrategia incremental puede evitar reprocesar toda la historia en cada ejecución. La clave es definir correctamente la columna de watermark y el comportamiento ante actualizaciones.
{{
config(
materialized='incremental',
unique_key='order_id',
partition_by={
"field": "order_created_at",
"data_type": "timestamp",
"granularity": "day"
}
)
}}
with source as (
select
cast(order_id as int64) as order_id,
cast(customer_id as int64) as customer_id,
timestamp(created_at) as order_created_at,
cast(status as string) as status,
cast(total_amount as numeric) as total_amount,
timestamp(updated_at) as updated_at
from {{ source('raw', 'orders') }}
{% if is_incremental() %}
where updated_at >= (
select coalesce(max(updated_at), timestamp('1900-01-01'))
from {{ this }}
)
{% endif %}
)
select *
from source
Advertencia sobre incremental models
Incremental no significa automáticamente más barato. Una mala estrategia de watermark puede provocar duplicados, pérdida de actualizaciones o reprocesamientos inesperados.
En producción hay que definir explícitamente qué significa "nuevo dato", cómo se manejan updates tardíos, cuál es la clave única y qué ventana de datos puede cambiar después de haber sido procesada.
Configuración del dbt_project.yml
El proyecto debería expresar la arquitectura en configuración, no solamente en convenciones verbales que cada desarrollador interpreta de una manera diferente.
name: analytics_platform
version: "1.0.0"
config-version: 2
profile: analytics_platform
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]
models:
analytics_platform:
staging:
+materialized: view
+schema: staging
intermediate:
+materialized: view
+schema: intermediate
marts:
+materialized: table
+schema: marts
Patrones de diseño para un proyecto empresarial
Una implementación Staff/Architect debe pensar más allá de la primera query correcta. El objetivo es crear límites que permitan escalar equipos, modelos y procesos.
Source of Truth
Declara las fuentes explícitamente mediante sources.yml. Esto mejora trazabilidad, documentación y tests sobre el origen de los datos.
Separación por capas
Staging para normalización, intermediate para composición técnica y marts para modelos consumibles por negocio.
Data Contracts
Define nombres, tipos, nulabilidad y tests críticos. Un modelo no debería depender silenciosamente de una estructura que puede cambiar sin aviso.
Entornos aislados
Separa targets de desarrollo y producción. Nunca diseñes un flujo donde un desarrollador pueda sobrescribir accidentalmente una tabla crítica.
Observabilidad
Tests, freshness, logs de ejecución y métricas de coste forman parte del sistema de datos, no son elementos accesorios.
Git como control
Versiona SQL, YAML y configuración. Las modificaciones de modelos deben pasar por revisión y controles automáticos antes de producción.
Framework de implementación paso a paso
Este es el flujo recomendado para pasar de una instalación local a una base preparada para crecer hacia un entorno empresarial.
Define proyecto, región, datasets y modelo de permisos antes de conectar dbt.
Crea un entorno virtual y fija las dependencias necesarias para que el runtime sea reproducible.
Verifica la instalación con dbt --version.
Ejecuta dbt init y valida que el perfil generado corresponda con el target esperado.
Ejecuta dbt debug antes de desarrollar modelos.
Documenta las tablas RAW y añade tests básicos sobre las claves críticas.
Normaliza nombres, tipos, timestamps y convenciones sin introducir lógica de negocio compleja.
Mueve las reglas de negocio a capas posteriores y diseña modelos orientados a los consumidores.
Cada cambio debe validar compilación, tests, dependencias y potenciales regresiones antes del merge.
Revisa bytes procesados, frecuencia de ejecución, materializaciones y crecimiento del DAG.
Comandos esenciales de dbt Core
Estos comandos forman un pequeño kit de diagnóstico y operación para cualquier proyecto dbt.
# Comprobar instalación
dbt --version
# Validar conexión y configuración
dbt debug
# Listar recursos
dbt ls
# Ejecutar todos los modelos
dbt run
# Ejecutar un modelo concreto
dbt run --select stg_customers
# Ejecutar un modelo y sus padres
dbt run --select +stg_customers
# Ejecutar un modelo y sus hijos
dbt run --select stg_customers+
# Ejecutar tests
dbt test
# Ejecutar modelos + tests
dbt build
# Compilar SQL/Jinja sin ejecutar
dbt compile
Preguntas frecuentes sobre dbt Core + BigQuery
¿Qué necesito para instalar dbt Core con BigQuery?
Necesitas Python, preferiblemente dentro de un entorno virtual, dbt Core junto con el adaptador de BigQuery, un proyecto de Google Cloud y credenciales con permisos suficientes para ejecutar jobs y trabajar con los datasets necesarios. En producción, utiliza identidades y permisos separados por entorno y evita almacenar secretos en Git.
¿Para qué sirve dbt init?
dbt init crea la estructura inicial de un proyecto dbt y permite configurar el perfil asociado al adaptador. Después puedes organizar modelos, fuentes, tests, macros, seeds, snapshots y documentación dentro de una estructura versionada.
¿Por qué utilizar staging models en dbt?
Staging crea una frontera técnica entre las tablas fuente y el resto de la arquitectura. Permite estandarizar nombres, tipos y convenciones antes de aplicar lógica de negocio. Esto reduce duplicación y hace que los modelos posteriores sean más fáciles de entender, probar y mantener.
Conclusión: instalar dbt es fácil; diseñarlo bien es la parte difícil
Instalar dbt Core con BigQuery puede resolverse en pocos comandos. La verdadera diferencia entre un proyecto experimental y una plataforma de datos profesional está en las decisiones que aparecen después: separación de entornos, gestión de credenciales, estructura de capas, contratos de datos, tests, materializaciones, incrementalidad y FinOps.
Si estás empezando, no intentes construir una arquitectura gigantesca desde el primer día. Empieza con sources → staging → marts, automatiza los controles fundamentales y evoluciona la complejidad cuando el volumen, los equipos o los casos de uso lo justifiquen.
Esa es la mentalidad que permite que dbt pase de ser simplemente una herramienta para ejecutar SQL a convertirse en una verdadera capa de Analytics Engineering.
