feat(ods): реализован ODS слой и DAG загрузки из STG
- Зачем: - подготовлена учебная реализация ODS слоя с типизацией, UPSERT и DQ, чтобы продолжить работу от STG к DDS/DM. - Что: - добавлены SQL-скрипты `sql/ods/*_ddl.sql`, `sql/ods/*_load.sql`, `sql/ods/*_dq.sql` для 9 сущностей bookings. - добавлены DAG `bookings_ods_ddl` и `bookings_to_gp_ods`, а также smoke-тесты для новых графов. - ODS DDL интегрирован в `sql/ddl_gp.sql`; документация и план обновлены под единый запуск через `make ddl-gp`. - Проверка: - `make test`. - `make ddl-gp`.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# DAG `bookings_to_gp_ods`: `stg` -> `ods` в Greenplum
|
||||
|
||||
Этот DAG — учебный пример загрузки типизированного слоя **ODS** из уже подготовленного слоя **STG**.
|
||||
Логика простая и каноничная: **SCD1 UPSERT** (обновляем изменившиеся записи, вставляем новые) + DQ-проверки.
|
||||
|
||||
## Что делает DAG
|
||||
|
||||
- Определяет `stg_batch_id`:
|
||||
- берёт из `dag_run.conf["stg_batch_id"]`, если передан;
|
||||
- иначе берёт последний **согласованный** `batch_id`, который есть во всех snapshot-таблицах STG
|
||||
(`airports`, `airplanes`, `routes`, `seats`).
|
||||
- Загружает 9 таблиц ODS (`airports`, `airplanes`, `routes`, `seats`, `bookings`, `tickets`,
|
||||
`flights`, `segments`, `boarding_passes`).
|
||||
- Для каждой таблицы выполняет пару задач `load -> dq`.
|
||||
- На загрузке использует дедупликацию внутри батча + UPSERT (SCD1).
|
||||
- Для snapshot-справочников (`airports`, `airplanes`, `routes`, `seats`) дополнительно
|
||||
синхронизирует ключи (удаляет из ODS записи, отсутствующие в выбранном STG-батче).
|
||||
|
||||
## Что должно быть готово перед запуском
|
||||
|
||||
1) Стек поднят:
|
||||
|
||||
```bash
|
||||
make up
|
||||
```
|
||||
|
||||
2) STG-слой создан и заполнен:
|
||||
|
||||
- запущен `bookings_stg_ddl` (или `make ddl-gp`);
|
||||
- хотя бы один раз выполнен DAG `bookings_to_gp_stage`.
|
||||
|
||||
3) ODS-таблицы созданы (один из вариантов):
|
||||
|
||||
- учебный: запустить DAG `bookings_ods_ddl`;
|
||||
- шорткат: `make ddl-gp` (в этом проекте он создаёт и STG, и ODS).
|
||||
|
||||
## Как запустить
|
||||
|
||||
1) Откройте Airflow UI: http://localhost:8080.
|
||||
2) Запустите DAG `bookings_to_gp_ods`.
|
||||
3) (Опционально) передайте `stg_batch_id` в конфиге запуска:
|
||||
|
||||
```json
|
||||
{"stg_batch_id": "manual__2026-02-22T12:00:00+00:00"}
|
||||
```
|
||||
|
||||
Если конфиг не передан, DAG автоматически возьмёт последний согласованный snapshot-батч.
|
||||
|
||||
## Граф зависимостей (упрощённо)
|
||||
|
||||
- `resolve_stg_batch_id`
|
||||
- Параллельно стартуют ветки:
|
||||
- `bookings -> tickets`
|
||||
- `airports`
|
||||
- `airplanes`
|
||||
- Далее:
|
||||
- `routes` после `airports` и `airplanes`
|
||||
- `seats` после `airplanes`
|
||||
- `flights` после `routes`
|
||||
- `segments` после `flights` и `tickets`
|
||||
- `boarding_passes` после `segments`
|
||||
- Финал: `finish_ods_summary` ждёт `dq_ods_boarding_passes` и `dq_ods_seats`.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
```bash
|
||||
make gp-psql
|
||||
```
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM ods.bookings;
|
||||
SELECT COUNT(*) FROM ods.tickets;
|
||||
SELECT COUNT(*) FROM ods.flights;
|
||||
|
||||
SELECT book_ref, COUNT(*)
|
||||
FROM ods.bookings
|
||||
GROUP BY 1
|
||||
HAVING COUNT(*) > 1;
|
||||
```
|
||||
|
||||
Ожидаемо: в последнем запросе `0` строк.
|
||||
|
||||
## Типичные ошибки
|
||||
|
||||
- `stg_batch_id не найден`:
|
||||
- передайте `stg_batch_id` в `dag_run.conf`, или
|
||||
- сначала загрузите STG через `bookings_to_gp_stage`.
|
||||
- Ошибки `relation "ods...." does not exist`:
|
||||
- не применён ODS DDL (`bookings_ods_ddl` / `make ddl-gp`).
|
||||
- Ошибки DQ по ссылочной целостности:
|
||||
- проверьте, что ODS DAG выполнялся с корректным `stg_batch_id` и без пропуска upstream задач.
|
||||
Reference in New Issue
Block a user