# airflow-dwh-gp-lab Учебный стенд для лабораторных по Data Engineering: **Airflow** оркестрирует загрузку данных из демо‑БД **bookings** (Postgres) в **Greenplum**. ## Зачем этот стенд Основная цель стенда — дать вам удобное место для лабораторных работ и будущей курсовой: вы построите небольшое аналитическое хранилище данных (DWH) на базе **Greenplum** и закрепите навыки: - моделирования данных (слои DWH, модели, витрины); - построения ETL/ELT; - работы с Airflow и Greenplum. В курсовой у нас один источник данных — демо‑БД **bookings**. В стенде уже есть готовые учебные примеры загрузки **bookings → STG → ODS → DDS → DM** в Greenplum, чтобы вы могли сфокусироваться на DWH‑части и не тратить время на инфраструктуру. ## Что внутри - **Airflow** (UI: http://localhost:8080, по умолчанию; логин/пароль: admin/admin) - **Greenplum** (single‑node для обучения; внешний порт по умолчанию `5435`) - **bookings-db** (Postgres с демо‑БД `demo`; внешний порт по умолчанию `5434`) - **PXF** как “транспорт” между Postgres и Greenplum (уже настроен в образе) ## Требования Стенд запускается в Docker и поднимает несколько сервисов (Airflow + Greenplum + 2×Postgres), поэтому важны ресурсы и настройки Docker. | Ресурс | Минимум | Рекомендуем | |---|---:|---:| | CPU | 2 ядра | 4+ ядер | | RAM | 8 GB | 16 GB | | Диск | 25–30 GB свободного места | 40+ GB (SSD) | Работает на **Linux**, а на **Windows** — при использовании **WSL2**. Потребуется `make`, Docker (`docker`) и Docker Compose (`docker compose`) или Docker Desktop. Для первого запуска нужен доступ в интернет (скачать образы и зависимости). Порты `8080`, `5433`, `5434`, `5435` должны быть свободны (или измените их в `.env`). Порты настраиваются в `.env`: `AIRFLOW_WEB_PORT`, `PGMETA_PORT`, `BOOKINGS_DB_PORT`, `GP_HOST_PORT`. Про PXF и технические детали стенда: [docs/stack.md](docs/stack.md). ## Быстрый старт (основной сценарий: bookings → STG → ODS → DDS → DM) 1) Скопируйте настройки: ```bash cp .env.example .env ``` 2) Поднимите стенд: ```bash make up # если make не установлен: docker compose up -d ``` 3) Инициализируйте демо‑БД bookings: ```bash make bookings-init # быстрое восстановление из seed-дампа (~18 сек), рекомендуется # make bookings-generate # альтернатива: полная генерация с нуля (занимает часы) ``` 4) Подготовьте объекты DWH в Greenplum (выберите один вариант): - Учебный вариант: в Airflow UI запустите DAG'и по порядку — `bookings_stg_ddl`, `bookings_ods_ddl`, `bookings_dds_ddl`, `bookings_dm_ddl`; - Технический шорткат: `make ddl-gp` (применяет DDL для STG, ODS, DDS и DM разом). 5) Запустите DAG'и загрузки данных по порядку: - `bookings_to_gp_stage` — загрузка в STG - `bookings_to_gp_ods` — загрузка в ODS - `bookings_to_gp_dds` — загрузка в DDS - `bookings_to_gp_dm` — загрузка в DM (витрины) 6) Проверьте результат в Greenplum: ```bash make gp-psql -- внутри psql: SELECT COUNT(*) FROM stg.bookings; SELECT COUNT(*) FROM stg.tickets; SELECT * FROM stg.bookings ORDER BY event_ts DESC LIMIT 10; SELECT COUNT(*) FROM ods.bookings; SELECT COUNT(*) FROM ods.tickets; SELECT COUNT(*) FROM dds.dim_routes; SELECT COUNT(*) FROM dds.fact_flight_sales; SELECT COUNT(*) FROM dm.sales_report; SELECT COUNT(*) FROM dm.route_performance; ``` Подробнее про логику DAG и проверки — `docs/bookings_to_gp_stage.md`. ## DAG-и в стенде Основные (для потока bookings → DWH): - `bookings_stg_ddl` — создаёт/обновляет весь STG слой для bookings (9 таблиц: bookings, tickets, airports, airplanes, routes, seats, flights, segments, boarding_passes; включая внешние `*_ext` через PXF); - `bookings_to_gp_stage` — генерирует учебный день в `bookings-db`, затем загружает данные в STG и выполняет DQ‑проверки. - `bookings_ods_ddl` — создаёт/обновляет ODS-таблицы по домену bookings. - `bookings_to_gp_ods` — загружает данные из STG в ODS (SCD1 UPSERT) и выполняет DQ‑проверки. - `bookings_dds_ddl` — создаёт/обновляет DDS-таблицы (`dim_*`, `fact_flight_sales`) по домену bookings. - `bookings_to_gp_dds` — загружает данные из ODS в DDS (SCD1/SCD2 + факт) и выполняет DQ‑проверки. - `bookings_dm_ddl` — создаёт/обновляет DM-витрины (sales_report, route_performance, passenger_loyalty, airport_traffic, monthly_overview). - `bookings_to_gp_dm` — загружает данные из DDS в DM (агрегированные витрины). ## Полезные команды ```bash make up # поднять стек make logs # логи airflow-webserver и airflow-scheduler make gp-psql # psql в Greenplum make bookings-psql # psql в демо-БД bookings (Postgres) make ddl-gp # применить DDL STG+ODS+DDS+DM к Greenplum вручную (вместо DDL-DAG) make down # остановить и удалить контейнеры/сети (volumes сохраняются) make clean # полный reset: удалить контейнеры/сети и volumes (данные будут потеряны) ``` ## Подключение через DBeaver (опционально) Перед подключением убедитесь, что стенд поднят (`make up`). ### Greenplum - `Host`: `localhost` - `Port`: значение `GP_HOST_PORT` из `.env` (по умолчанию `5435`) - `Database`: значение `GP_DB` из `.env` (по умолчанию `gp_dwh`) - `Username`: значение `GP_USER` (по умолчанию `gpadmin`) - `Password`: значение `GP_PASSWORD` (по умолчанию `gpadmin`) ### bookings-db (Postgres, демо-БД `demo`) - `Host`: `localhost` - `Port`: значение `BOOKINGS_DB_PORT` из `.env` (по умолчанию `5434`) - `Database`: `demo` - `Username`: значение `BOOKINGS_DB_USER` (по умолчанию `bookings`) - `Password`: значение `BOOKINGS_DB_PASSWORD` (по умолчанию `bookings`) ## Документация - [Учебные задания](educational-tasks.md) - [План тестирования/проверок и негативные кейсы](TESTING.md) - [Дополнительные заметки и технические детали](docs/README.md) - [Детали по STG DAG](docs/bookings_to_gp_stage.md) - [Детали по ODS DAG](docs/bookings_to_gp_ods.md) - [Детали по DDS DAG](docs/bookings_to_gp_dds.md) - [Детали по DM DAG](docs/bookings_to_gp_dm.md) ## Типичные проблемы и решения | Проблема | Решение | |----------|---------| | Airflow UI не открывается | Дождитесь сообщения `Listening at: http://0.0.0.0:8080` в логах (`make logs`) | | `database "demo" does not exist` в bookings‑DAG | Вы сделали reset с удалением volumes (`make clean` / `docker compose down -v`). Запустите `make bookings-init` (быстрое восстановление из дампа, ~18 сек) и повторите DAG. | | Ошибка `bookings.jobs должен быть >= 1` | Проверьте значение `BOOKINGS_JOBS` в `.env` — оно должно быть целым числом >= 1. По умолчанию `BOOKINGS_JOBS=1` (синхронная генерация). При `BOOKINGS_JOBS>1` генерация идёт параллельно через dblink. | | Ошибка подключения к Greenplum | Убедитесь, что контейнер `greenplum` имеет статус `healthy` (`docker compose ps`) | | `protocol "pxf" does not exist` | Перезапустите `greenplum` и повторите `bookings_stg_ddl`/`make ddl-gp` — расширение `pxf` создаётся автоматически при старте контейнера. | | DAG `bookings_to_gp_stage` ругается на отсутствующие таблицы stg | Запустите `bookings_stg_ddl` (или выполните `make ddl-gp`), затем повторите запуск | | Порты 8080/5433/5434/5435 заняты | Остановите локальные сервисы или измените порты в `.env` | ## Благодарности - **Postgres Pro** — за демо‑БД bookings и генератор данных `demodb`: https://github.com/postgrespro/demodb (лицензия MIT: https://github.com/postgrespro/demodb/blob/main/LICENSE). - **woblerr** — за Docker-сборку Greenplum: https://github.com/woblerr/docker-greenplum (образ: `woblerr/greenplum`, лицензия MIT: https://github.com/woblerr/docker-greenplum/blob/master/LICENSE).