Repositorio de referencia para el Proyecto #4 — Construyendo un Data Warehouse: modelo dimensional sobre Northwind con dbt y Snowflake del Curso de Fundamentos de Ingeniería de Datos.
En este proyecto tendrás la oportunidad de construir un modelo dimensional utilizando Snowflake y dbt.
Al finalizar este proyecto habrás aprendido a:
- Crear un modelo dimensional a partir de un modelo relacional
- Materializar modelos de dbt en Snowflake
- Organizar los datos de forma modular, siguiendo la estructura modular propuesta por dbt
Trabajarás con el dataset Northwind. Los CSV crudos están incluidos en este repositorio bajo datasets/northwind/ (misma fuente que el enlace del curso).
Modelo relacional de referencia (origen):
Nota: Algunos archivos contienen columnas que son imágenes serializadas como texto y contienen caracteres no estándar. Esas columnas no son necesarias para el ejercicio de modelado y pueden removerse de los datasets. En esta solución, el script
scripts/preprocess_seeds.pylimpia y excluye columnas problemáticas (por ejemploPhotoen empleados) antes de cargar los seeds.
La solución final debe:
- Crear un modelo dimensional que permita modelar de manera analítica el dataset
- Incluir al menos 2 tablas de hechos
- Estar construida utilizando dbt
Se recomienda Snowflake. Es ampliamente usada en la industria y el proyecto se puede ejecutar con su versión gratuita: crear cuenta Snowflake.
El objetivo principal es practicar modelado dimensional; la herramienta es el medio para lograrlo.
- Descarga los CSV del dataset Northwind (o usa los de
datasets/northwind/en este repo). - Carga el dataset en tu plataforma elegida (Snowflake, PostgreSQL, DuckDB, etc.). Se recomienda usar seeds en dbt.
Instala dbt de manera local (librería de Python) y conéctalo con Snowflake.
Guía de referencia: Easy guide to create your local dbt + Snowflake playground
Lectura recomendada: Master Dimensional Modeling
Para los modelos de dbt, sigue el enfoque por capas (raw → staging → marts). Lecturas sugeridas:
- Data modeling techniques for more modularity
- Intro to Data Build Tool (dbt) — Create your first project!
a) Zona raw
- Crea una tabla
raw_TABLE_NAMEpor cada CSV. - Representa el CSV tal cual viene, sin transformaciones de negocio.
b) Zona stg
- Crea
stg_TABLE_NAMEa partir de las tablas raw. - Aplica transformaciones ligeras: renombrar columnas, estandarizar formatos, columnas derivadas,
CASE WHENpara limpiar valores.
c) Zona marts
- A partir de staging, construye el modelo dimensional.
- Crea dimensiones (
dim_) y hechos (fct_ofact_). - Ejemplos:
dim_customer,dim_product,fct_sales. - El modelo debe responder preguntas de negocio con datos desnormalizados.
Lectura recomendada: Building a data quality framework with dbt
Crea al menos 3 pruebas de calidad con dbt. Ideas:
- Validar que no existan nulos en campos clave (Order ID, Customer ID)
- Fechas dentro de un rango válido
- Valores numéricos (ventas, cantidad) no negativos
Crear 2 bases en Snowflake (producción y desarrollo) y un pipeline CI/CD con GitHub Actions que despliegue el código a Snowflake y mueva datos según variables de entorno en el proyecto dbt.
Técnicos
- The Data Warehouse Toolkit (Kimball) — al menos los primeros 4 capítulos
- Intro to Data Build Tool (dbt)
Recomendados
- What is a Data Warehouse: Basic Architecture
- Building a Data Warehouse: Basic Architectural principles
- Data Warehouse Pipeline: Basic Concepts & Roadmap
- A Data Warehouse Implementation on AWS
- Data modeling techniques for modern data warehouses
- Data modeling techniques for more modularity
- The 5 essential data quality checks in analytics
Esta sección describe cómo reproducir y ejecutar la implementación de referencia de este repositorio.
| Requisito del enunciado | En este repo |
|---|---|
| Modelo dimensional analítico | Sí — capas RAW → STAGING → INT → SNAPSHOTS → MARTS |
| Al menos 2 tablas de hechos | Parcial — fact_orders (pedidos). Extensión natural: fact_order_details a grano línea |
| Construido con dbt | Sí |
| Zona raw / stg / marts | Sí — seeds en RAW, vistas stg_*, tablas dim_* y fact_orders en MARTS |
| Calidad de datos (≥ 3 pruebas) | Sí — tests en schema.yml + tests singulares en tests/ |
Objetos principales: dimensiones SCD2 (dim_customer, dim_employee, dim_shipper), dim_date, hecho fact_orders (una fila por pedido).
Cualquier persona que clone este repo debe poder ejecutar el proyecto con su propia cuenta de Snowflake. No hay credenciales compartidas en el repositorio.
- Cuenta de Snowflake (trial válido)
- Python 3.12 y
git bash(macOS/Linux; en Windows usar WSL)- Rol con al menos:
USAGEen warehouse,USAGEyCREATE SCHEMAen la base de datos,USAGEen el rol
-- Ejemplo (ajusta nombres según tu .env)
USE ROLE <tu-rol>;
USE WAREHOUSE <tu-warehouse>;
CREATE DATABASE IF NOT EXISTS NORTHWIND_DIMENSIONAL_DEV;En cuentas trial con rol amplio suele bastar con crear la base y ejecutar dbt.
git clone <url-de-este-repo>
cd modelo-dimensional-northwind
python3.12 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txtcp .env.example .env
# Edita .env con TU cuenta, usuario, rol, warehouse y database.Elige una forma de autenticación (ver también Opciones de autenticación):
- Contraseña (recomendado si tienes usuario/contraseña nativos): añade
SNOWFLAKE_PASSWORD=<tu-contraseña>en.envy usa los comandos del paso 5 sin--target. - OAuth en el navegador (SSO): no hace falta
SNOWFLAKE_PASSWORD; en el paso 5 usa--target deven todos los comandosdbt.sh.
CREATE DATABASE IF NOT EXISTS NORTHWIND_DIMENSIONAL_DEV;
-- O el nombre que configuraste en SNOWFLAKE_DATABASEpython scripts/preprocess_seeds.py
python scripts/verify_seeds.pyverify_seeds.py debe imprimir OK: 7/7 seeds match manifest y salir con código 0.
Opción A — contraseña (requiere SNOWFLAKE_PASSWORD en .env):
./scripts/dbt.sh debug
./scripts/dbt.sh buildOpción B — OAuth en el navegador (si no usas contraseña o ves 251006: Password is empty):
./scripts/dbt.sh debug --target dev
./scripts/dbt.sh build --target devdbt build carga seeds, ejecuta snapshots, materializa modelos y corre tests en orden de dependencias. Con conexión correcta deberías ver algo como 54 PASS (16 modelos, 7 seeds, 3 snapshots, 28 tests).
| Target | Comandos del paso 5 | Requiere |
|---|---|---|
dev_password (por defecto en profiles.yml) |
./scripts/dbt.sh debug y build |
SNOWFLAKE_PASSWORD en .env |
dev |
./scripts/dbt.sh debug --target dev y build --target dev |
Cuenta con SSO; se abre el navegador la primera vez |
El script ./scripts/dbt.sh carga dbt_snowflake_oauth_patch.py (útil para OAuth; no afecta el flujo con contraseña).
Probado en clone limpio: pasos 1–4 sin Snowflake; paso 5 con
--target devcompleta el build y dejaFACT_ORDERS=STG_ORDERS= 830 enNORTHWIND_DIMENSIONAL_DEV.
Modelo dimensional de referencia (objetivo del curso):
Diagrama de referencia con tres hechos (fact_orders, fact_order_details, fact_inventory_snapshot) y dimensiones conformadas. Esta implementación cubre el MVP centrado en fact_orders (ver tabla en Qué incluye esta implementación); el diagrama sirve como mapa para extensiones.
Pipeline dbt implementado (capas en Snowflake):
flowchart LR
raw[(datasets/northwind/*.csv)] --> pre["preprocess_seeds.py"]
pre --> seeds[(seeds/*.csv)]
seeds --> RAW[("Snowflake: RAW")]
RAW --> STG["staging (views)"]
STG --> INT["intermediate (views)"]
INT --> SNAP[("SNAPSHOTS (SCD2)")]
SNAP --> DIM["dim_* (tables)"]
INT --> FACT["fact_orders (table)"]
DIM --> FACT
Capas: RAW (seeds) → STAGING → INT → SNAPSHOTS (SCD2) → MARTS (dim_*, fact_orders).
Tras un clone limpio, puedes validar:
-
./scripts/dbt.sh debug→ "All checks passed!" -
python scripts/verify_seeds.py→OK: 7/7 seeds match manifest -
./scripts/dbt.sh build→ 16 modelos, 28 tests de datos, 0 errores (conexión y permisos correctos) -
SELECT COUNT(*) FROM MARTS.FACT_ORDERS=SELECT COUNT(*) FROM STAGING.STG_ORDERS= 830 - Esquema
SNAPSHOTS:snapshot_customer_history,snapshot_employee_history,snapshot_shipper_history
Tests singulares incluidos:
assert_stg_orders_count_eq_fact_orders— misma cardinalidad staging vs hechoassert_fact_orders_scd_dims_temporal_window—order_datedentro de la ventana SCD2 de cada dimensión
Northwind es un dataset de ejemplo de Microsoft. Ver DATA-LICENSE.md.
Código del proyecto: MIT.
