- Зачем:
- STG-слой использовал legacy-имена (batch_id, load_dttm, src_created_at_ts),
тогда как ODS/DDS/DM уже работали с каноном (_load_id, _load_ts, event_ts).
Студент видел разные имена для одного понятия — это убрано.
- Что:
- переименованы колонки в 9 STG DDL: batch_id→_load_id, load_dttm→_load_ts,
src_created_at_ts→event_ts; добавлен NOT NULL для _load_id во всех таблицах.
- обновлены 9 STG Load, 9 STG DQ, 9 ODS Load, 9 ODS DQ (INSERT/SELECT/WHERE).
- обновлены DAG-файлы bookings_to_gp_stage.py и bookings_to_gp_ods.py
(встроенный SQL резолвера, комментарии; Python-идентификаторы не тронуты).
- обновлены тесты и ~15 документов (naming_conventions, PRD, db_schema,
design-docs, qa-plan, README, TESTING и др.).
- Проверка:
- grep -rn 'load_dttm\|src_created_at_ts' sql/ airflow/ tests/ — 0 совпадений.
- make test — 4 passed.
- e2e-etl: day1 прошёл полностью, day2 стартовал без ошибок.
170 lines
10 KiB
Markdown
170 lines
10 KiB
Markdown
# 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).
|