feat(dds): перенесён lookup аэропортов на ods.routes, обновлена документация задания
- Зачем:
- fact_flight_sales брал airport_sk через dds.dim_routes (студенческое задание SCD2);
на ветке main без реализованного dim_routes все airport_sk были NULL,
и эталонные витрины sales_report/airport_traffic становились бесполезны.
- Что:
- fact_flight_sales_load.sql: добавлен subquery ods_rte (ROW_NUMBER по ods.routes),
dep/arr airport_sk теперь через ods.routes (эталон); airplane_sk — через dim_routes (point-in-time).
- analyst_spec.md: удалены STG-задания (1.1–1.3) и ods.routes (2.3), добавлены секции
«Почему STG уже реализован» и «Пересчёт факта», исправлен ODS intro, перенумерованы части.
- assignment_design.md: обновлены таблицы эталон/задание, порядок выполнения; убраны
validate_stg и check_ods_routes_rowcount из структуры валидационного DAG.
- db_schema.md: статус уточнён («реализовано в ветке solution»), добавлена оговорка
о заглушках на main, DQ-контракт дополнен примечанием.
- Проверка:
- make test → 4 passed, 9 skipped.
- ручная проверка: TRUNCATE dds.fact_flight_sales → перезапуск DDS DAG →
COUNT(departure_airport_sk) должен равняться COUNT(*).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,15 +20,14 @@
|
||||
|------|-----------------------------------------------------------------|
|
||||
| DM | `sales_report` |
|
||||
| DDS | `fact_flight_sales`, `dim_airports` (SCD1), `dim_tariffs` (SCD1), `dim_calendar` |
|
||||
| ODS | `bookings`, `tickets`, `segments`, `flights`, `boarding_passes`, `airports` |
|
||||
| STG | `bookings`, `tickets`, `segments`, `flights`, `boarding_passes`, `airports` |
|
||||
| ODS | `bookings`, `tickets`, `segments`, `flights`, `boarding_passes`, `airports`, `routes` |
|
||||
| STG | весь слой: `bookings`, `tickets`, `segments`, `flights`, `boarding_passes`, `airports`, `airplanes`, `seats`, `routes` |
|
||||
|
||||
### Задание студенту
|
||||
|
||||
| Слой | Таблицы | Что нового для студента |
|
||||
|------|-------------------------------------------------------------------|--------------------------------------------------|
|
||||
| STG | `airplanes`, `seats`, `routes` | Практика по аналогии с эталоном |
|
||||
| ODS | `airplanes`, `seats`, `routes` | Практика SCD1 UPSERT по аналогии |
|
||||
| ODS | `airplanes`, `seats` | Практика TRUNCATE+INSERT по аналогии с эталоном |
|
||||
| DDS | `dim_airplanes` (SCD1), `dim_passengers` (SCD1), `dim_routes` (SCD2) | **SCD2 — ключевой вызов курсовой** |
|
||||
| DM | `airport_traffic`, `monthly_overview`, `route_performance`, `passenger_loyalty` | Разная сложность (от простой к сложной) |
|
||||
|
||||
@@ -38,14 +37,13 @@
|
||||
|
||||
Студенту рекомендуется (но не обязательно) двигаться в таком порядке:
|
||||
|
||||
1. **STG** (airplanes, seats, routes) — разминка, по аналогии
|
||||
2. **ODS** (airplanes, seats, routes) — закрепление UPSERT
|
||||
3. **DDS** dim_airplanes, dim_passengers (SCD1) — новые измерения
|
||||
4. **DDS** dim_routes (**SCD2**) — ключевой вызов
|
||||
5. **DM** airport_traffic — простая витрина, похожа на sales_report
|
||||
6. **DM** route_performance — TRUNCATE+INSERT, SCD2-агрегация по BK
|
||||
7. **DM** monthly_overview — двухуровневая агрегация
|
||||
8. **DM** passenger_loyalty — самая сложная, пересчёт истории
|
||||
1. **ODS** (airplanes, seats) — практика TRUNCATE+INSERT
|
||||
2. **DDS** dim_airplanes, dim_passengers (SCD1) — новые измерения
|
||||
3. **DDS** dim_routes (**SCD2**) — ключевой вызов
|
||||
4. **DM** airport_traffic — простая витрина, похожа на sales_report
|
||||
5. **DM** route_performance — TRUNCATE+INSERT, SCD2-агрегация по BK
|
||||
6. **DM** monthly_overview — двухуровневая агрегация
|
||||
7. **DM** passenger_loyalty — самая сложная, пересчёт истории
|
||||
|
||||
Порядок выстроен от простого к сложному. Каждый шаг опирается на опыт
|
||||
предыдущего.
|
||||
@@ -83,14 +81,9 @@
|
||||
|
||||
```
|
||||
bookings_validate
|
||||
├── validate_stg
|
||||
│ ├── check_stg_airplanes_exists (таблица создана, >0 строк)
|
||||
│ ├── check_stg_seats_exists
|
||||
│ └── check_stg_routes_exists
|
||||
├── validate_ods
|
||||
│ ├── check_ods_airplanes_rowcount (ODS >= STG по кол-ву уникальных BK)
|
||||
│ ├── check_ods_seats_rowcount
|
||||
│ ├── check_ods_routes_rowcount
|
||||
│ └── check_ods_no_null_pks (PK not null)
|
||||
├── validate_dds
|
||||
│ ├── check_dim_airplanes_exists
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Схема БД DWH (Bookings → Greenplum)
|
||||
|
||||
> **Статус:** Все слои реализованы (STG, ODS, DDS, DM).
|
||||
> **Статус:** Все слои реализованы в ветке `solution` (STG, ODS, DDS, DM).
|
||||
> На ветке `main` студенческие таблицы ODS (`airplanes`, `seats`), DDS-измерения
|
||||
> (`dim_airplanes`, `dim_passengers`, `dim_routes`) и студенческие DM-витрины
|
||||
> (`airport_traffic`, `route_performance`, `monthly_overview`, `passenger_loyalty`)
|
||||
> — заглушки (`SELECT 1;`). Данные появятся после реализации заданий.
|
||||
|
||||
Архитектура хранилища данных (DWH) для учебного проекта Airflow + Greenplum.
|
||||
Источник — демо-БД `bookings` (Postgres). Документ даёт цельный взгляд «сверху»;
|
||||
@@ -250,7 +254,9 @@ Degenerate keys: `book_ref`, `ticket_no`, `flight_id`, `book_date`, `seat_no`.
|
||||
## Ключевые договорённости
|
||||
|
||||
- **Нейминг полей**: [`naming_conventions.md`](naming_conventions.md)
|
||||
- **DQ-проверки**: SQL-скрипты с `RAISE EXCEPTION` (не отдельный DQ-слой)
|
||||
- **DQ-проверки**: SQL-скрипты с `RAISE EXCEPTION` (не отдельный DQ-слой).
|
||||
На ветке `main` студенческие DQ-скрипты (`airplanes_dq.sql`, `seats_dq.sql`,
|
||||
student dims/DM) — заглушки (`SELECT 1;`) без проверок.
|
||||
- **Инкремент STG**: для `tickets` опорная дата — из `bookings.book_date`
|
||||
- **Point-in-time JOIN**: факт ↔ `dim_routes` по `[valid_from, valid_to)`
|
||||
- **Суррогатные ключи**: `MAX(sk) + ROW_NUMBER()` (не SERIAL — GP-специфика)
|
||||
|
||||
Reference in New Issue
Block a user