Módulo 8: Project Kioskos Lakehouse
Presentación del módulo: el capstone, el lakehouse completo de Kiosko
Por qué existe este módulo
Los siete módulos anteriores construyeron, uno a la vez, cada garantía específica que un formato de tabla le agrega a un archivo Parquet suelto. El módulo 1 cargó kiosko.fact_orders como la primera tabla Iceberg real. El módulo 2 mapeó su anatomía completa —catálogo, metadata, manifest list, manifest files, archivos de datos—. El módulo 3 viajó en el tiempo sobre kiosko.dim_product y recuperó el margen correcto de P002 sin ninguna columna de historia. El módulo 4 evolucionó el esquema de kiosko.dim_store, agregando country sin reescribir un solo archivo. El módulo 5 particionó kiosko.fact_orders_at_scale —diez millones de filas— de forma oculta, y evolucionó ese spec hacia adelante. El módulo 6 aplicó el cambio de P002 con MERGE INTO (representativo, vía Spark) y con table.upsert() (ejecutado de verdad). El módulo 7 nombró los catálogos de producción y podó, con evidencia real, los snapshots que ya no aportaban nada.
Cada uno de esos siete módulos vivió en su propio directorio de trabajo, con su propio catálogo kiosko_catalog.db recién creado desde cero, probando una garantía a la vez. Ninguno de los siete te mostró el lakehouse completo: las cinco tablas de Kiosko —fact_orders, dim_store, dim_product, dim_date, fact_orders_at_scale— viviendo juntas, en el mismo catálogo, en el mismo namespace, listas para responder la misma pregunta de negocio que ya respondieron seis motores distintos en las seis guías anteriores de este ecosistema: ¿cuánto vendió Kiosko esta semana (106.15), y cuál es el margen correcto de P002 una vez que se reconstruye su historia (10.8)?
Este módulo es ese ensamblaje. No introduce ninguna capacidad nueva de Iceberg —cada pieza que vas a usar ya la construiste, con tus propias manos, en un módulo anterior—. Lo que hace es exactamente lo que hizo el módulo 8 de data-modeling-for-analytics-guide y el módulo 8 de dbt-analytics-engineering-guide antes: reunir siete piezas dispersas en un solo warehouse dimensional, verificado de punta a punta, con los mismos números exactos que esas dos guías ya confirmaron con sus propios motores.
El caso que nos acompaña: el lakehouse completo, no una demo más
Kiosko —la cadena de tres tiendas de conveniencia y su app de delivery— tiene, al cerrar este módulo, cinco tablas Iceberg reales conviviendo en el mismo namespace kiosko:
kiosko.fact_orders: la semana fija de 40 órdenes, revenue total106.15(S01=38.3,S02=38.8,S03=29.05).kiosko.dim_store: las tres tiendas, concountrypoblada desde su primer commit (Bogotá→Colombia,Lima→Peru,Santiago→Chile) — el resultado final de la evolución de esquema que el módulo 4 ya demostró paso a paso.kiosko.dim_product: cuatro productos, cero columnas de historia, con el cambio deP002(snacks/0.60→health-snacks/0.68, vigencia2026-08-15) aplicado contable.overwrite(), y el estado anterior recuperable con time travel — el resultado final del módulo 3.kiosko.dim_date: el calendario de agosto de 2026, 31 filas, la pieza que ningún módulo anterior había construido todavía — la única tabla genuinamente nueva de este capstone.kiosko.fact_orders_at_scale: diez millones de filas, particionada porstore_idy evolucionada conDayTransformsobreorder_ts— el resultado final del módulo 5.
La pregunta que este módulo responde no es técnica — es de negocio, la misma que ya respondieron data-engineering-foundations-guide, python-for-data-engineering-guide, data-modeling-for-analytics-guide, dbt-analytics-engineering-guide y spark-and-distributed-processing-guide, cada una con su propio motor: ¿cuánto vendió Kiosko, y cuál es el margen real de P002 una vez que se reconstruye su historia? La respuesta, sobre Iceberg, sigue siendo 106.15 de revenue y 10.8 de margen correcto — y la forma de llegar a ese margen correcto ya no necesita ni una sola columna valid_from.
Una analogía: la maqueta final, con las cinco piezas ya fabricadas
Un estudio de arquitectura que pasó siete semanas fabricando, por separado, los cimientos, la estructura, el sistema eléctrico, las divisiones interiores y el paisajismo de una maqueta a escala, llega a la octava semana con todas las piezas terminadas sobre la mesa de trabajo — cada una probada por separado, ninguna todavía unida a las demás. La octava semana no fabrica ninguna pieza nueva: ensambla. Encaja los cimientos con la estructura, conecta el sistema eléctrico a través de las paredes ya construidas, coloca las divisiones interiores en su lugar exacto, y rodea todo con el paisajismo que hasta ese momento vivía en su propia caja. El resultado no es más sofisticado técnicamente que cualquiera de las siete piezas individuales — es, por primera vez, una maqueta completa, la única versión que un cliente puede mirar de un vistazo y entender como un solo edificio.
Este módulo es esa octava semana. Cada tabla que vas a ensamblar ya la fabricaste, probada y verificada, en un módulo anterior. Lo que faltaba era la mesa donde las cinco piezas conviven juntas.
Diagrama: de dónde vienen las cinco piezas
flowchart TB
M1["Modulo 1:\nkiosko.fact_orders\n40 filas, 106.15"]
M3["Modulo 3:\nkiosko.dim_product\nsnap_v1, time travel, 10.8/9.36"]
M4["Modulo 4:\nkiosko.dim_store\n+country (evolucion de esquema)"]
M5["Modulo 5:\nkiosko.fact_orders_at_scale\nparticionada + evolucionada"]
M6["Modulo 6:\ntable.upsert()\nMERGE INTO (representativo)"]
NEW["NUEVO en este modulo:\nkiosko.dim_date\n31 filas, agosto 2026"]
M1 --> L3["L3: rebuilding\nthe star"]
M4 --> L3
NEW --> L3
M3 --> L4["L4: reproducing\nP002 con time travel"]
L3 --> L4
M5 --> L5["L5: evolving and\npartitioning at scale"]
M6 --> L6["L6: merging updates\nthe native way"]
L4 --> L6
L5 --> L7["L7: what Kiosko\nstill needs"]
L6 --> L7
L7 --> L8["L8: proyecto de cierre\nde TODA la guia"]
El mapa de este módulo
Leccion Que resuelve
──────── ──────────────────────────────────────────────────────────────
L1 (esta) Por que existe este modulo, las cinco piezas, el mapa
L2 El brief -- por que Kiosko necesita UN lakehouse, no siete
demos sueltas
L3 Ensambla fact_orders, dim_store (con country) y dim_date --
las tres tablas que NO cambian de estado -- como tablas
Iceberg reales, en un solo catalogo
L4 dim_product sin columnas de historia + el star completo
unido con time travel: margen correcto 10.8 vs roto 9.36
L5 fact_orders_at_scale: 10,000,000 filas particionadas,
evolucionadas, con la franquicia nueva bajo el spec nuevo
L6 El mismo cambio de P002 aplicado con table.upsert() --
la via nativa -- verificado byte a byte contra L4
L7 Cierre de ecosistema: las 7 guias hermanas y que resuelve
cada una sobre lo que este lakehouse deja pendiente
L8 Proyecto final: el lakehouse completo, un solo script,
assert automaticos -- CIERRA la guia completa
Lo que este módulo NO vuelve a enseñar
Cada mecanismo que vas a ver ejecutarse en las lecciones 3 a 6 ya fue enseñado, paso a paso, con su propia analogía y sus propios errores comunes, en un módulo anterior. Este módulo no repite esas explicaciones — las usa. Si algún paso de código te resulta confuso, la referencia exacta a dónde se enseñó por primera vez está señalada en cada lección: la evolución de esquema de dim_store se explicó a fondo en el módulo 4, la mecánica de table.overwrite() y el time travel en el módulo 3, PartitionSpec y su evolución en el módulo 5, y table.upsert() en el módulo 6. Este capstone asume que ya los conoces, y se concentra en algo que ningún módulo anterior podía mostrar en aislamiento: cómo se ven, juntas, en el mismo catálogo, las cinco tablas de un lakehouse real.
Errores comunes
Esperar que este módulo enseñe una técnica de Iceberg que los siete anteriores no cubrieron. Qué pasa: alguien llega a este módulo esperando aprender algo nuevo sobre el formato en sí —una API que no vio antes, una capacidad de Iceberg todavía no mencionada—. Por qué pasa: "capstone" suena, en algunos cursos, a "el módulo más avanzado", y es fácil asumir que "avanzado" significa "técnicamente nuevo". Cómo detectarlo: si terminas la lección 3 sin reconocer ningún método de la API de PyIceberg que ya usaste antes, revisa: load_catalog(), create_table(), append(), overwrite(), scan(snapshot_id=...), update_spec(), upsert() — todos vienen de los siete módulos anteriores. Cómo corregirlo: este módulo es de integración, no de técnica nueva — el valor está en ver las cinco piezas convivir, verificadas contra los mismos números exactos que data-modeling-for-analytics-guide y dbt-analytics-engineering-guide ya confirmaron con motores distintos.
Asumir que kiosko.dim_date ya existía en algún módulo anterior, y buscarla ahí. Qué pasa: alguien busca, en los módulos 1 a 7, el código que crea kiosko.dim_date, y no lo encuentra. Por qué pasa: el DISEÑO de esta guía nombra dim_date desde la lección 5 del módulo 1 —como una de las cinco tablas que el namespace kiosko va a contener "para el final de esta guía"—, y es razonable asumir que "nombrada" significa "ya construida". Cómo detectarlo: si tu búsqueda en los módulos anteriores no encuentra ningún create_table("kiosko.dim_date", ...), no es un error tuyo — esa tabla, deliberadamente, se dejó para este módulo. Cómo corregirlo: la lección 3 de este módulo es la primera vez que kiosko.dim_date se crea de verdad, con el mismo esquema exacto (date_key, calendar_date, day_of_week, month, quarter, year, is_weekend) que data-modeling-for-analytics-guide ya usó para su propio dim_date.
Ejercicios
Ejercicio 1 — Antes de leer la lección 3, predice qué tres tablas de Kiosko NO necesitan reproducir ningún mecanismo de evolución o time travel en este módulo, y por qué. Piensa en cuáles de las cinco tablas del lakehouse tienen un estado final simple —una sola versión, sin historia que reconstruir— frente a las que sí lo tienen.
Ver solución
kiosko.fact_orders, kiosko.dim_store y kiosko.dim_date no necesitan reproducir ningún mecanismo de evolución o time travel en este módulo: las tres se cargan en su estado final, de una sola vez. fact_orders nunca cambió en ningún módulo anterior —siempre fueron las mismas 40 filas—; dim_store ya tiene country desde su primer commit en este módulo, porque el mecanismo de cómo se agrega esa columna sin reescribir datos ya quedó demostrado, paso a paso, en el módulo 4 — repetirlo aquí sería reenseñar, no ensamblar; y dim_date es una tabla nueva sin ningún estado previo que reconstruir. En cambio, kiosko.dim_product sí necesita reproducir el mecanismo completo (V1, overwrite(), snap_v1) porque el punto central de todo este capstone es demostrar que el margen correcto (10.8) sigue siendo recuperable con time travel dentro del lakehouse ensamblado — y kiosko.fact_orders_at_scale necesita reproducir su evolución de partición porque la convivencia de dos spec_id distintos es, en sí misma, parte de lo que este módulo verifica.
Ejercicio 2 — Sin mirar el mapa de este módulo, enumera las siete guías hermanas del ecosistema data-engineering-ecosystem que ya conoces hasta este punto. Cuenta cuántas puedes nombrar de memoria antes de leer la lección 7.
Ver solución
Hasta este punto de la guía, ya se nombraron explícitamente: data-engineering-foundations-guide (el overwrite-partition no atómico, módulo 4), python-for-data-engineering-guide (Python de producción, nombrado en el DISEÑO), data-modeling-for-analytics-guide (el dim_product historizado a mano, el hilo canónico de toda la guía), dbt-analytics-engineering-guide (dbt snapshot, comparado en el módulo 6), spark-and-distributed-processing-guide (el Parquet de origen y el particionado por carpetas, módulo 5), y airflow-and-declarative-orchestration-guide (nombrada por la frontera, sin implementar). La lección 7 de este módulo agrega tres más a esta lista con evidencia específica del capstone completo: streaming-with-kafka-and-flink-guide, data-reliability-and-governance-guide, aws-core-services-guide, advanced-sql-querying-guide y cost-optimization-caching-guide — siete guías hermanas en total, cada una con su propia frontera exacta.
Ejercicio 3 — Explica, en tus propias palabras, por qué la lección 8 de este módulo se llama "proyecto" y no "resumen". En 2-3 frases, justifica por qué un capstone de esta guía necesita un script ejecutable con assert, y no le bastaría con una tabla que recuerde los números ya vistos.
Ver solución
Un resumen solo repetiría, en prosa, números que ya se vieron en los siete módulos anteriores —una afirmación sin evidencia nueva—. Un proyecto ejecutable, en cambio, reconstruye las cinco tablas desde cero, en un directorio nuevo, y verifica con assert que el resultado sigue siendo exactamente el mismo: no "confía en que sigue siendo 106.15", sino que lo vuelve a probar, en el mismo estilo de "verificar, no confiar" que cada proyecto de cierre de esta guía —módulos 1, 3, 4, 5, 6 y 7— ya aplicó. La diferencia entre "resumen" y "proyecto" es, exactamente, la diferencia entre recordar un resultado y reproducirlo.
Resumen y siguiente paso
En esta lección viste por qué existe este módulo: siete módulos anteriores construyeron, cada uno, una garantía específica de Iceberg sobre una tabla aislada de Kiosko — este módulo las reúne en un solo lakehouse, con las cinco tablas conviviendo en el mismo catálogo. Conociste el mapa completo de las ocho lecciones, y la única pieza genuinamente nueva de este capstone: kiosko.dim_date, el calendario que ningún módulo anterior había construido todavía.
Antes de avanzar deberías poder: nombrar las cinco tablas del lakehouse completo de Kiosko y de qué módulo viene el mecanismo de cada una; y explicar por qué este módulo no enseña ninguna técnica nueva de Iceberg, sino que integra las siete ya aprendidas.
La lección 2 traduce la necesidad de este ensamblaje en un brief concreto: qué le pide, en sus propias palabras, la gerencia de Kiosko al equipo de datos, y por qué "siete demos sueltas" ya no le alcanza.
Recursos
- PyIceberg — documentación oficial (quickstart), la misma base de instalación y catálogo que sostiene los ocho módulos de esta guía. py.iceberg.apache.org. En inglés.
- Apache Iceberg — documentación oficial, versión de referencia 1.11.0, el mapa completo de conceptos que este capstone ensambla. iceberg.apache.org/docs/latest. En inglés.
- DISEÑO de
data-modeling-for-analytics-guide— fuente dedim_date(esquemadate_key/calendar_date/day_of_week/month/quarter/year/is_weekend) y del cambio canónico deP002que este capstone reproduce con time travel.src/guides/data-modeling-for-analytics-guide/DISENO.md. En español. - DISEÑO de
dbt-analytics-engineering-guide— segunda confirmación independiente de los mismos números de margen (10.8/9.36) que este capstone verifica.src/guides/dbt-analytics-engineering-guide/DISENO.md. En español. - DISEÑO de esta guía — el mapa completo de los ocho módulos, incluida la sección completa de este módulo 8.
src/guides/lakehouse-and-iceberg-guide/DISENO.md. En español.