Глубокая переработка документации
This commit is contained in:
@@ -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)
|
||||
@@ -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`.
|
||||
@@ -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"`).
|
||||
|
||||
@@ -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, примеры запросов и типичные ошибки.
|
||||
@@ -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
@@ -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`)
|
||||
Reference in New Issue
Block a user