Files
airflow-greenplum/docs/archive/stg_naming_unification_plan.md
T
ddadmin 6655326caa docs(all): реструктурирована документация — docs/internal/ заменён на design/, reference/, archive/, plans/
- Зачем:
  - docs/internal/ превратился в свалку: дизайн-документы, ревью, планы и справочники лежали вперемешку.
  - архивные планы были неотличимы от живых документов.
- Что:
  - docs/internal/ удалён; файлы распределены по docs/design/, docs/reference/, docs/archive/, docs/plans/, docs/assignment/.
  - educational-tasks.md убран из корня в архив (устарел).
  - обновлены все перекрёстные ссылки в AGENTS.md, TODO.md, README.md, docs/README.md и внутри design/reference/.
  - актуализированы architecture_review.md (статус DM-слоя), db_schema.md (DM-слой), TESTING.md, dag_execution_order.md, pxf_bookings.md.
  - добавлены заглушки docs/assignment/README.md и docs/plans/README.md.
- Проверка:
  - make test && make lint
  - rg 'docs/internal' --glob '!docs/archive/*' — должно быть пусто.
2026-03-10 23:02:41 +03:00

119 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Унификация нейминга служебных полей в STG
## Контекст
В STG-слое используются legacy-имена служебных полей (`batch_id`, `load_dttm`, `src_created_at_ts`), а начиная с ODS — каноничные (`_load_id`, `_load_ts`, `event_ts`). Студент видит разные имена для одного понятия. Цель — привести STG к канону, убрав расхождение.
> **Breaking change (dev-only).** Это ломающее переименование колонок. Миграционный шаг (ALTER TABLE … RENAME COLUMN) не предусмотрен. DDL-файлы используют `CREATE TABLE IF NOT EXISTS`, поэтому сами по себе они не пересоздадут существующие таблицы с новыми именами колонок. План предполагает заранее пересозданную среду (например, `make down && make up`) или ручной `DROP TABLE` / `DROP SCHEMA` перед `make ddl-gp`. Обратная совместимость не обеспечивается.
## Маппинг
| Legacy (STG сейчас) | Канон (ODS/DDS/DM) |
|---|---|
| `batch_id` | `_load_id` |
| `load_dttm` | `_load_ts` |
| `src_created_at_ts` | `event_ts` |
### Оговорка про `event_ts` в snapshot-справочниках
В транзакционных STG-таблицах (bookings, tickets, flights, segments, boarding_passes) поле `src_created_at_ts` действительно хранит время события из источника — переименование в `event_ts` семантически точно.
В snapshot-справочниках (airports, airplanes, routes, seats) это поле заполняется `now()` при загрузке, т.е. по факту это ещё одно load-time, а не время события. Тем не менее мы сохраняем единое имя `event_ts` как **учебное упрощение** — ради консистентной структуры STG-таблиц. Это зафиксировано как осознанный trade-off: единообразие важнее семантической точности в справочниках. В `naming_conventions.md` нужно добавить соответствующую оговорку (раздел 4, «Time Rule»).
## Что НЕ переименовываем
- PL/pgSQL переменная `v_batch_id` — это локальная переменная, не колонка
- Python-функция `_resolve_stg_batch_id`, переменная `stg_batch_id`, task_id `resolve_stg_batch_id` — это Python/Airflow-идентификаторы
- XCom-ключи, ссылающиеся на task_id
## Порядок выполнения
### Шаг 1: STG DDL (9 файлов)
`sql/stg/{bookings,tickets,flights,segments,airports,airplanes,routes,seats,boarding_passes}_ddl.sql`
В каждом: `batch_id``_load_id`, `load_dttm``_load_ts`, `src_created_at_ts``event_ts`.
### Шаг 2: STG Load (9 файлов)
`sql/stg/{bookings,tickets,flights,segments,airports,airplanes,routes,seats,boarding_passes}_load.sql`
INSERT-списки, SELECT, WHERE, комментарии — те же 3 замены.
### Шаг 3: STG DQ (9 файлов)
`sql/stg/{bookings,tickets,flights,segments,airports,airplanes,routes,seats,boarding_passes}_dq.sql`
WHERE-условия (`batch_id = v_batch_id``_load_id = v_batch_id`), RAISE-сообщения, комментарии.
### Шаг 4: ODS Load (9 файлов)
Два подтипа — обрабатывать по-разному.
#### 4a: Транзакционные таблицы (5 файлов)
`sql/ods/{bookings,tickets,flights,segments,boarding_passes}_load.sql`
SELECT из STG: `s.batch_id``s._load_id`, `s.load_dttm``s._load_ts`, `s.src_created_at_ts``s.event_ts`. Убрать лишние алиасы (`s.src_created_at_ts AS event_ts` → просто `s.event_ts`).
#### 4b: Snapshot-справочники (4 файла)
`sql/ods/{airports,airplanes,routes,seats}_load.sql`
Здесь `event_ts` отсутствует в целевой ODS-таблице — менять только ссылки на STG-колонки: `s.batch_id``s._load_id`, `s.load_dttm``s._load_ts`, `s.src_created_at_ts``s.event_ts` (только в ORDER BY / WHERE, где они читают из STG). ODS-колонка `_load_ts` по-прежнему заполняется через `now()`, это не меняется.
### Шаг 5: ODS DQ (9 файлов)
`sql/ods/{bookings,tickets,flights,segments,airports,airplanes,routes,seats,boarding_passes}_dq.sql`
`WHERE batch_id =``WHERE _load_id =`, RAISE-сообщения.
### Шаг 6: DAG-файлы (2 файла)
- `airflow/dags/bookings_to_gp_stage.py` — комментарий про `batch_id`
- `airflow/dags/bookings_to_gp_ods.py` — встроенный SQL-запрос резолвера: все `batch_id` как колонка → `_load_id`, `load_dttm``_load_ts`. Python-имена не трогаем.
### Шаг 7: Тесты (3 файла)
- `tests/test_ods_snapshot_integration.py` — inline DDL и INSERT в тестах
- `tests/test_dags_smoke.py` — комментарии
- `tests/test_ods_sql_contract.py` — docstring
### Шаг 8: Документация (~15 файлов)
- `docs/internal/naming_conventions.md` — убрать legacy-исключение (секция 5/STG), убрать переходный маппинг (секция 6), добавить оговорку про `event_ts` в snapshot-справочниках (секция 4)
- `docs/internal/db_schema.md` — описания STG-полей
- `docs/internal/bookings_stg_design.md` — дизайн STG
- `docs/internal/bookings_ods_design.md` — маппинг STG→ODS, SQL-примеры
- `docs/internal/qa-plan.md` — SQL-запросы проверок
- `docs/internal/architecture_review.md` — архитектурные заметки
- `docs/internal/bookings_stg_code_review.md` — код-ревью
- `docs/bookings_to_gp_stage.md` — описание STG DAG, примеры полей
- `docs/bookings_to_gp_ods.md` — описание ODS DAG
- `docs/dag_execution_order.md` — порядок выполнения DAG
- `educational-tasks.md` — учебные задания
- `README.md` — SQL-примеры в README
- `TESTING.md` — чек-лист тестирования
### Шаг 9: Верификация
```bash
# 1. Проверить SQL и Python — не должно быть колонок batch_id
# (допустимы только: v_batch_id, stg_batch_id, resolve_stg_batch_id)
grep -rn 'batch_id' sql/stg/ sql/ods/ airflow/dags/ tests/ --include='*.sql' --include='*.py'
# 2. Ноль совпадений по старым именам в коде
grep -rn 'load_dttm' sql/ airflow/dags/ tests/ --include='*.sql' --include='*.py'
grep -rn 'src_created_at_ts' sql/ airflow/dags/ tests/ --include='*.sql' --include='*.py'
# 3. Проверить документацию — не должно быть старых имён как актуальных
# (допустимы упоминания в историческом контексте)
grep -rn 'batch_id\|load_dttm\|src_created_at_ts' docs/ educational-tasks.md README.md TESTING.md
# 4. Тесты и линтер
make test
make fmt && make lint
```
## Итого: ~55 файлов, ~3 механические замены в каждом