Files
airflow-greenplum/docs/bookings_to_gp_ods.md
T
ddadmin 5972bcc2d8 refactor(all): унифицированы служебные поля STG — переход на канонический нейминг
- Зачем:
  - 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 стартовал без ошибок.
2026-03-10 00:07:08 +03:00

4.0 KiB

DAG bookings_to_gp_ods: stg -> ods в Greenplum

Этот DAG — учебный пример загрузки типизированного слоя ODS из уже подготовленного слоя STG. Логика простая и каноничная: SCD1 UPSERT (обновляем изменившиеся записи, вставляем новые) + DQ-проверки.

Что делает DAG

  • Определяет stg_batch_id:
    • берёт из dag_run.conf["stg_batch_id"], если передан;
    • иначе берёт последний согласованный _load_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-батче).
  • Для flights дополнительно добирает рейсы из истории stg.flights, если на них ссылаются stg.segments выбранного батча (чтобы сохранить ссылочную целостность segments.flight_id -> flights.flight_id).

Что должно быть готово перед запуском

  1. Стек поднят:
make up
  1. STG-слой создан и заполнен:
  • запущен bookings_stg_ddl (или make ddl-gp);
  • хотя бы один раз выполнен DAG bookings_to_gp_stage.
  1. 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 в конфиге запуска:
{"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.

Как проверить результат

make gp-psql
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 задач.