Глубокая переработка документации

This commit is contained in:
2026-01-09 18:48:18 +03:00
parent 16da5d0aae
commit 5f3e32c031
11 changed files with 340 additions and 530 deletions
+17
View File
@@ -0,0 +1,17 @@
# Документация
Этот каталог содержит дополнительные материалы к учебному стенду.
## Быстрый путь (для менти)
- [Быстрый старт и команды](../README.md)
- [Учебные задания](../educational-tasks.md)
- [План тестирования и проверки](../TESTING.md)
- [Главный учебный DAG: bookings → stg](bookings_to_gp_stage.md)
## Технические детали (опционально)
- [Как устроен Docker-стенд (образы, Connections, переменные окружения)](stack.md)
- [PXF в этом проекте (проектная реализация)](internal/pxf_bookings.md)
- [Дизайн stg для bookings (черновик)](internal/bookings_stg_design.md)
- [Про время/UTC в bookings (черновик)](internal/bookings_tz.md)
+100
View File
@@ -0,0 +1,100 @@
# DAG `bookings_to_gp_stage`: `bookings-db` → `stg` в Greenplum
Этот DAG — основной учебный пример в стенде. Он показывает путь данных из источника **Postgres**
(`bookings-db`, демо‑БД `demo`) в сырой слой **STG** в **Greenplum** с инкрементальной загрузкой
и простой проверкой качества данных.
## Что делает DAG
- В источнике (`bookings-db`) генерирует следующий учебный день данных в `bookings.bookings`
(генератор всегда “шагает” вперёд от `max(book_date)`).
- В Greenplum загружает инкремент в `stg.bookings` через внешнюю таблицу `stg.bookings_ext` (PXF).
- Сверяет количество строк между источником (за окно инкремента) и загруженным батчем.
## Что должно быть готово перед запуском
1) Стек поднят:
```bash
make up
```
2) Демо‑БД bookings установлена и содержит данные:
```bash
make bookings-init
```
3) В Greenplum созданы `stg.bookings_ext` и `stg.bookings` (выберите один вариант):
- учебный вариант: запустить DAG `bookings_stg_ddl` в Airflow UI;
- технический шорткат: `make ddl-gp`.
4) Airflow Connections:
- `bookings_db` — подключение к источнику `bookings-db`;
- `greenplum_conn` — подключение к Greenplum.
По умолчанию они задаются через переменные окружения `AIRFLOW_CONN_...` в `docker-compose.yml`,
поэтому могут не отображаться в UI — для `PostgresOperator` это нормально.
## Как запустить
1) Откройте Airflow UI: http://localhost:8080 (admin/admin).
2) Запустите DAG `bookings_to_gp_stage` вручную (Trigger DAG).
3) Дождитесь статуса Success у всех задач.
## Как это работает внутри (по шагам)
1) `generate_bookings_day`
- выполняет `sql/src/bookings_generate_day_if_missing.sql` в `bookings-db`;
- если `bookings.bookings` пустая — вызывает `generate(...)` на `BOOKINGS_INIT_DAYS`;
- иначе — вызывает `continue(...)`, добавляя ровно один следующий день.
2) `load_bookings_to_stg`
- выполняет `sql/stg/bookings_load.sql` в Greenplum;
- берёт строки из `stg.bookings_ext`, которые попадают в новое окно инкремента;
- вставляет их в `stg.bookings`, добавляя тех.колонки:
- `src_created_at_ts` (опорная метка времени для инкремента),
- `load_dttm`,
- `batch_id={{ run_id }}`.
3) `check_row_counts`
- выполняет `sql/stg/bookings_dq.sql` в Greenplum;
- считает количество строк в источнике за то же окно инкремента и сравнивает с количеством строк,
вставленных в `stg.bookings` для текущего `batch_id`;
- при расхождении делает `RAISE EXCEPTION` с понятным текстом.
4) `finish_summary`
- логирует краткую сводку в конце запуска.
## Как проверить результат
```bash
make gp-psql
```
Примеры запросов:
```sql
SELECT COUNT(*) FROM stg.bookings;
SELECT
src_created_at_ts,
load_dttm,
batch_id
FROM stg.bookings
ORDER BY src_created_at_ts DESC
LIMIT 10;
```
## Типичные ошибки
- `database "demo" does not exist`: демо‑БД не установлена → выполните `make bookings-init`.
- Ошибки про `stg.bookings_ext`/`stg.bookings`: не применён DDL → запустите `bookings_stg_ddl` или `make ddl-gp`.
- Ошибки PXF (`protocol "pxf" does not exist`, connection refused): перезапустите `greenplum` и повторите DDL.
Для технических деталей см. `docs/internal/pxf_bookings.md`.
+2 -2
View File
@@ -68,7 +68,7 @@ DDL будет добавлен в `sql/ddl_gp.sql` в блоке DDL для Gre
- считаем режим `full` — загружаем все строки из `stg.bookings_ext`.
- При последующих запусках:
- читаем `max(src_created_at_ts)` из `stg.bookings` за все предыдущие загрузки;
- считаем, что нужно загрузить только строки, где `src_created_at_ts` больше этой максимальной метки и не позже конца текущего учебного дня.
- загружаем строки, где `src_created_at_ts` больше этой максимальной метки (верхняя граница по времени не задаётся).
Таким образом, вся логика инкремента «замкнута» на один техно‑столбец `src_created_at_ts`, который студент потом сможет использовать и на следующих слоях (например, в CDC‑логике).
@@ -88,7 +88,7 @@ DDL будет добавлен в `sql/ddl_gp.sql` в блоке DDL для Gre
- `dag_id`: `bookings_to_gp_stage`.
- Основные параметры:
- `batch_id` (по умолчанию `{{ ds_nodash }}`) — метка батча, которая попадает в `stg.bookings.batch_id`;
- `batch_id` (в текущей реализации `{{ run_id }}`) — метка батча, которая попадает в `stg.bookings.batch_id`;
- подключения:
- `bookings_db_conn_id` — Airflow connection к `bookings-db` (в коде DAG — `BOOKINGS_CONN_ID = "bookings_db"`);
- `greenplum_conn_id` — Airflow connection к Greenplum (`GREENPLUM_CONN_ID = "greenplum_conn"`).
-80
View File
@@ -1,80 +0,0 @@
# Мини‑README по учебному DAG bookings_to_gp_stage (черновик)
_Внутренний файл, чтобы не забыть договорённости. Перед итоговой сдачей документацию по блоку bookings/STG нужно будет аккуратно собрать и переписать._
## 1. Что делает DAG
- DAG `bookings_to_gp_stage` показывает учебный поток:
- источник: демо‑БД `bookings-db` (Postgres, схема `bookings`, таблица `bookings.bookings`);
- при каждом запуске генерируется один учебный день данных (идемпотентно);
- данные из `bookings.bookings` переливаются в сырой слой `stg.bookings` в Greenplum через PXF‑внешнюю таблицу `stg.bookings_ext`.
- Слой `stg` задуман как «сырой»:
- все бизнес‑колонки (`book_ref`, `book_date`, `total_amount`) хранятся как `TEXT`;
- есть тех.колонки `src_created_at_ts`, `load_dttm`, `batch_id`.
Подробный дизайн описан в `docs/internal/bookings_stg_design.md`.
## 2. Что нужно, чтобы DAG завёлся
Минимальные предпосылки:
- Стенд поднят: `make up`.
- Демо‑БД bookings инициализирована: `make bookings-init`.
- В Greenplum применён DDL (созданы схема `stg` и таблицы `stg.bookings_ext` / `stg.bookings`):
- учебный вариант: запустить DAG `bookings_stg_ddl` (он использует `sql/stg/bookings_ddl.sql`);
- технический шорткат: `make ddl-gp` применяет все DDL разом вручную. Команда сама не вызывается при старте контейнеров, её нужно запустить явно.
- В Airflow есть коннекты:
- `greenplum_conn` — к Greenplum;
- `bookings_db` — к сервису `bookings-db`.
По умолчанию они задаются через переменные окружения `AIRFLOW_CONN_...` в docker-compose,
поэтому могут не отображаться в UI, но `PostgresOperator` найдёт их по `conn_id`. При желании
их можно создать/отредактировать вручную через Admin → Connections.
## 3. Последовательность задач в DAG
- `generate_bookings_day`:
- PostgresOperator к `bookings-db`;
- выполняет SQL `/sql/src/bookings_generate_day_if_missing.sql`;
- скрипт смотрит на `max(book_date)` в `bookings.bookings`:
- если база пустая — берёт стартовую дату из GUC и генерирует `bookings.init_days` суток;
- если данные уже есть — добавляет один следующий учебный день после `max(book_date)` и пишет NOTICE с интервалом генерации.
- `load_bookings_to_stg`:
- PostgresOperator к Greenplum;
- выполняет SQL `/sql/stg/bookings_load.sql`;
- считает «старый» максимум `src_created_at_ts` (по предыдущим батчам) и грузит только новые строки из `stg.bookings_ext`, заполняя `src_created_at_ts`, `load_dttm`, `batch_id={{ ds_nodash }}`.
- `check_row_counts`:
- PostgresOperator к Greenplum;
- выполняет SQL `/sql/stg/bookings_dq.sql`;
- за то же окно инкремента считает количество строк в источнике и в `stg.bookings` (по текущему `batch_id`);
- при расхождении делает `RAISE EXCEPTION` с понятным текстом ошибки.
- `finish_summary`:
- логирует итог выполнения DAG за одно срабатывание.
## 4. Как этим пользоваться студенту (черновой сценарий)
1. Поднять стенд и подготовить источники:
- `make up` (Airflow инициализируется автоматически при первом старте)
- `make bookings-init`
- `make ddl-gp`
2. Открыть Airflow UI (`http://localhost:8080`) и включить DAG `bookings_to_gp_stage`.
3. Вызвать `Trigger` DAG (дату логического запуска можно оставить по умолчанию — она используется только как метка `batch_id`).
4. Посмотреть:
- в `bookings-db` ― что появился день с бронированиями;
- в Greenplum (`make gp-psql`) — данные в `stg.bookings`:
- `SELECT * FROM stg.bookings LIMIT 10;`
- `SELECT src_created_at_ts, load_dttm, batch_id FROM stg.bookings ORDER BY src_created_at_ts DESC LIMIT 10;`
5. Перезапустить DAG ещё несколько раз и увидеть, что:
- генерация в `bookings.bookings` идёт по одному дню вперёд от текущего `max(book_date)`;
- в `stg.bookings` появляются только новые записи (delta), помеченные разными `batch_id`.
## 5. Примечания «на потом»
- Текущая документация по блоку bookings/STG разбросана:
- `README.md` (общий обзор стенда),
- `docs/internal/bookings_tz.md` (источник bookings),
- `docs/internal/pxf_bookings.md` (PXF),
- `docs/internal/bookings_stg_design.md` (дизайн STG),
- этот файл (мини‑README по DAG).
- В будущем всё это нужно будет собрать в одну понятную историю для студента:
- отдельный раздел «Учебный пример: bookings → stg → dwh»;
- скриншоты DAG, примеры запросов и типичные ошибки.
+1 -1
View File
@@ -143,7 +143,7 @@
- `docker-compose.yml` (сервис `greenplum`: `build`, `hostname`, env, healthcheck)
- `pxf/init/10_pxf_bookings.sh` (ensure‑логика)
- `pxf/init/start_greenplum_with_pxf.sh` (старт контейнера)
- `README.md` (раздел «Greenplum + PXF: свой образ»)
- `docs/stack.md` (раздел «Greenplum + PXF: свой образ»)
## 10. Известная проблема: после `docker compose stop/start` Greenplum может упасть (auth для PXF)
+125
View File
@@ -0,0 +1,125 @@
# Технические детали стенда (Docker / Airflow / Greenplum)
Этот документ не обязателен для прохождения лабораторных, но полезен, если вы:
- хотите понять, как устроен стенд “под капотом”;
- меняете конфиги/зависимости и пересобираете образы;
- отлаживаете проблемы со стартом Greenplum/PXF или Connections в Airflow.
## Make (опционально, но удобно)
Если `make` не установлен, можно пользоваться `docker compose ...`.
Но с `make` команды короче и проще.
Установка `make` (если нужно):
- Linux (Debian/Ubuntu): `sudo apt install -y make`
- macOS: `brew install make`
- Windows:
- WSL: `sudo apt install -y make`
- Chocolatey: `choco install make`
- Scoop: `scoop install make`
Примеры:
```bash
make up
make logs
make gp-psql
```
## Airflow Connections
Готовые DAG по умолчанию подключаются к БД через Airflow Connections:
- `greenplum_conn` — Greenplum;
- `bookings_db` — демо‑БД bookings (`bookings-db`).
В `docker-compose.yml` Connections задаются через переменные окружения `AIRFLOW_CONN_...`,
поэтому они могут не отображаться в UI — для DAG это нормально.
Если нужно завести вручную:
1) Airflow UI → Admin → Connections → Add a new record
2) Пример для Greenplum:
- Conn Id: `greenplum_conn`
- Conn Type: `Postgres`
- Host: `greenplum`
- Schema: `gp_dwh`
- Login/Password: `gpadmin` / `gpadmin`
- Port: `5432`
## Greenplum + PXF: свой образ
Greenplum собирается из собственного `Dockerfile.greenplum`, чтобы:
- не ловить проблемы с правами/`chown` при bind‑mount конфигов;
- держать PXF‑конфиги и JDBC‑драйвер внутри образа;
- делать старт контейнера идемпотентным.
При старте контейнера:
- seed‑конфиги PXF докладываются в `PXF_BASE` на persistent volume;
- создаются каталоги `PXF_BASE/run` и `PXF_BASE/logs`;
- расширение `pxf` создаётся автоматически, когда Greenplum становится доступен (с ретраями).
Полезные команды:
```bash
make build # пересобрать образы
docker compose ps # проверить health
```
Перезапись seed‑файлов в `PXF_BASE`:
- `PXF_SEED_OVERWRITE=1` — перезаписать конфиги при старте;
- `PXF_SYNC_ON_START=1` — выполнить `pxf cluster sync` при старте.
Подробнее: `docs/internal/pxf_bookings.md`.
## Airflow: свой образ
Airflow тоже собирается из собственного `Dockerfile.airflow`, чтобы зависимости ставились при сборке,
а не во время старта контейнеров.
Если меняли `airflow/requirements.txt` или `Dockerfile.airflow`, пересоберите образы:
```bash
make build
make up
```
## Локальное окружение разработчика (uv)
Локальным окружением управляет `uv` — он создаёт `.venv` из `pyproject.toml` / `uv.lock`.
```bash
uv sync
make test
make lint
make fmt
```
Не устанавливайте зависимости через `pip install --user ...` — это часто ломает окружение и IDE.
## Переменные окружения (`.env`)
Все настройки лежат в `.env` (шаблон: `.env.example`).
### Greenplum
- `GP_USER`, `GP_PASSWORD`, `GP_DB`
- `GP_PORT` — внутренний порт в Docker-сети (обычно `5432`), внешний порт на хосте фиксирован на `5435`
### bookings-db (Postgres)
- `BOOKINGS_DB_USER`, `BOOKINGS_DB_PASSWORD`
- `BOOKINGS_DB_PORT` — внешний порт (по умолчанию `5434`)
- `BOOKINGS_START_DATE` — стартовая дата модельного времени
- `BOOKINGS_INIT_DAYS` — сколько дней генерировать при первом `make bookings-init`
- `BOOKINGS_JOBS` — число джобов генератора (по умолчанию `1`)
### CSV pipeline (побочный пример)
- `CSV_DIR` — путь к каталогу с CSV внутри контейнеров Airflow (по умолчанию `/opt/airflow/data`)
- `CSV_ROWS` — количество строк, генерируемых DAG (по умолчанию `1000`)