docs(main): очистка docs, адаптация для студентов, починка ссылок
Шаг 5 плана main/solution split: - Удалены внутренние документы с main: plans/, archive/, PRD, assignment_design, pxf_bookings, bookings_tz, benchmarks, TODO.md - AGENTS.md: убраны упоминания plans/archive, agent-dag-testing - Починены 19 битых markdown-ссылок во всех оставшихся файлах - bookings_ods_design: airplanes/seats помечены как студенческие, обновлён DAG-граф (routes без зависимости от airplanes) - bookings_dds_design: обновлено описание DQ факта (student SK) - bookings_to_gp_dds: обновлена DQ-семантика для main - qa-plan: уточнено — ods.airplanes/seats пусты by design на main Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,244 +0,0 @@
|
||||
# PRD: Greenplum Bookings DWH
|
||||
|
||||
> Курсовая работа для курса [DE Roadmap](https://github.com/dementev-dev/de-roadmap).
|
||||
> Статус: **ЧЕРНОВИК v0.1** | Дата: 2026-03-08
|
||||
|
||||
---
|
||||
|
||||
## 1. Видение продукта
|
||||
|
||||
**Greenplum Bookings DWH** — учебный стенд, на котором студент самостоятельно строит
|
||||
end-to-end ETL-пайплайн: от базы-источника до аналитических витрин.
|
||||
|
||||
Стенд имитирует реальную рабочую задачу Data-инженера:
|
||||
- Есть «боевая» система-источник (bookings-db), в которой каждый день появляются
|
||||
новые данные — как в жизни, без ограниченного объёма.
|
||||
- Есть DWH на Greenplum с классическими слоями (STG → ODS → DDS → DM).
|
||||
- Есть Airflow, оркестрирующий загрузку.
|
||||
- Есть ТЗ от «аналитика» с описанием ожидаемых таблиц и маппингов.
|
||||
|
||||
Студент получает **частично реализованный пайплайн** (эталонный вертикальный срез)
|
||||
и **дореализует остальное** по ТЗ — SQL-скрипты и таски в DAG.
|
||||
|
||||
### Почему именно bookings?
|
||||
|
||||
Домен бронирования авиабилетов выбран не ради предметной области, а благодаря
|
||||
генератору данных: каждый вызов `make bookings-generate-day` создаёт новый день
|
||||
с реалистичным объёмом. Это даёт бесконечный поток инкрементальных данных —
|
||||
как в настоящей production-системе.
|
||||
|
||||
---
|
||||
|
||||
## 2. Целевая аудитория и пререквизиты
|
||||
|
||||
**Кто:** студенты курса DE Roadmap, дошедшие до раздела «Курсовая работа».
|
||||
|
||||
**Что уже умеют** (к моменту старта):
|
||||
- Git: ветки, PR, merge, GitFlow
|
||||
- SQL: JOIN, CTE, оконные функции, планы запросов, моделирование (3NF, звезда, SCD)
|
||||
- Python: скрипты, pandas, базовое ООП
|
||||
- Docker: запуск контейнеров, логи, docker-compose
|
||||
- Airflow: понятие DAG, операторы, зависимости, UI, логи
|
||||
- Greenplum: распределение по сегментам, skew, EXPLAIN, отличие от Postgres
|
||||
|
||||
**Уровень:** уверенный джун, готовящийся к первым собеседованиям.
|
||||
|
||||
---
|
||||
|
||||
## 3. Учебные результаты (Learning Outcomes)
|
||||
|
||||
После выполнения курсовой студент умеет:
|
||||
|
||||
1. **Проектировать и реализовывать ETL-пайплайн** по слоям DWH
|
||||
(STG → ODS → DDS → DM) на реальном стеке Airflow + Greenplum.
|
||||
2. **Читать ТЗ от аналитика** (маппинги, описания таблиц) и превращать его
|
||||
в работающий SQL + DAG.
|
||||
3. **Писать идемпотентные загрузки** с инкрементальностью (HWM, _load_id,
|
||||
delete+insert), понимая, почему в Greenplum не используется MERGE.
|
||||
4. **Реализовывать SCD1/SCD2** и объяснять, когда что применяется.
|
||||
5. **Настраивать и проверять Data Quality** — понимает, зачем DQ-проверки
|
||||
и как их встроить в пайплайн.
|
||||
6. **Работать с Greenplum** как с MPP: выбирать distribution key,
|
||||
понимать heap vs AO, читать планы запросов.
|
||||
7. **Оформить проект как портфолио** — репозиторий пригоден для упаковки
|
||||
в резюме как реальный опыт работы с Airflow и Greenplum.
|
||||
|
||||
---
|
||||
|
||||
## 4. Скоуп
|
||||
|
||||
### В скоупе (In Scope)
|
||||
|
||||
| Компонент | Описание |
|
||||
|-----------------------|-------------------------------------------------------------|
|
||||
| Источник данных | bookings-db (Postgres) с генератором дней |
|
||||
| DWH | Greenplum, 4 слоя: STG, ODS, DDS, DM |
|
||||
| Оркестрация | Apache Airflow (PostgresOperator + SQL-файлы) |
|
||||
| Федеративный доступ | PXF (чтение из Postgres в Greenplum) |
|
||||
| Инфраструктура | Docker Compose (полный стенд в одной команде) |
|
||||
| Data Quality | DQ-проверки, встроенные в DAG |
|
||||
| Документация | README, ТЗ, design docs, naming conventions |
|
||||
|
||||
### Вне скоупа (Out of Scope)
|
||||
|
||||
| Что | Почему |
|
||||
|-----------------------|-------------------------------------------------------------|
|
||||
| Kafka / стриминг | Отдельный стенд в курсе |
|
||||
| BI-инструменты | Фокус на ETL, не на визуализации |
|
||||
| CI/CD | Избыточно для курсовой |
|
||||
| Spark / Trino / dbt | Отдельные стенды в курсе |
|
||||
| Второй источник | Усложнение без пропорциональной учебной ценности |
|
||||
| CSV-пайплайн | Вынести в [airflow-manual](https://github.com/dementev-dev/airflow-manual) |
|
||||
| Облачная инфраструктура | Всё локально, через Docker |
|
||||
|
||||
---
|
||||
|
||||
## 5. Архитектура стенда
|
||||
|
||||
### Сервисы (Docker Compose)
|
||||
|
||||
```
|
||||
bookings-db (Postgres 16) ──PXF──> Greenplum 6.27
|
||||
├── stg.* (стейджинг)
|
||||
├── ods.* (операционное хранилище)
|
||||
├── dds.* (детальное хранилище)
|
||||
└── dm.* (витрины)
|
||||
|
||||
pgmeta (Postgres 16) ─────────────> Airflow (webserver + scheduler)
|
||||
```
|
||||
|
||||
### Слои DWH
|
||||
|
||||
| Слой | Назначение | Паттерн загрузки | Кол-во таблиц |
|
||||
|------|-----------------------------------|---------------------------|---------------|
|
||||
| STG | Зеркало источника | TRUNCATE + INSERT (batch) | 9 |
|
||||
| ODS | Нормализованное хранилище | SCD1 UPSERT | 9 |
|
||||
| DDS | Измерения + факты (Kimball) | SCD1/SCD2 + fact load | 7 (6D + 1F) |
|
||||
| DM | Аналитические витрины | HWM-инкремент | 5 |
|
||||
|
||||
### Сущности
|
||||
|
||||
| STG / ODS | DDS | DM |
|
||||
|----------------------|--------------------------|-----------------------|
|
||||
| bookings | dim_airports | airport_traffic |
|
||||
| tickets | dim_airplanes | monthly_overview |
|
||||
| airports | dim_passengers | passenger_loyalty |
|
||||
| airplanes | dim_routes (SCD2) | route_performance |
|
||||
| routes | dim_calendar | sales_report |
|
||||
| seats | dim_tariffs | |
|
||||
| flights | fact_flight_sales | |
|
||||
| segments | | |
|
||||
| boarding_passes | | |
|
||||
|
||||
---
|
||||
|
||||
## 6. Педагогическая модель
|
||||
|
||||
Подробности — в [assignment_design.md](assignment_design.md).
|
||||
|
||||
### Принцип: «Эталонный срез + ТЗ»
|
||||
|
||||
Студент получает репозиторий, в котором:
|
||||
|
||||
1. **Эталонный вертикальный срез** — полностью реализованная цепочка
|
||||
`sales_report` и все её источники вниз по слоям (STG → ODS → DDS → DM).
|
||||
2. **ТЗ от аналитика** — описание остальных таблиц
|
||||
(analyst_spec.md — будет создан на Этапе 3, см. TODO.md).
|
||||
3. **Частично готовый DAG** — студент добавляет свои таски по аналогии.
|
||||
4. **Валидационный DAG** — студент запускает для самоконтроля.
|
||||
|
||||
### Что делает студент
|
||||
|
||||
- Пишет DDL, SQL-загрузки, DQ-проверки для назначенных таблиц
|
||||
- Добавляет таски в существующий DAG
|
||||
- Проверяет результат через валидационный DAG и запросы в Greenplum
|
||||
|
||||
### Что студент НЕ делает
|
||||
|
||||
- Не поднимает инфраструктуру с нуля (Docker Compose дан)
|
||||
- Не пишет DAG с нуля (шаблон дан)
|
||||
- Не настраивает Airflow Connections (преднастроены)
|
||||
- Не работает с PXF-конфигурацией (настроен)
|
||||
|
||||
---
|
||||
|
||||
## 7. Ветки и workflow
|
||||
|
||||
```
|
||||
main (стартовое состояние)
|
||||
├── Эталонный срез: реализованные таблицы + DAG
|
||||
├── ТЗ от аналитика
|
||||
├── Инфраструктура (Docker, Make, PXF)
|
||||
├── Заглушки / TODO-маркеры для студенческих заданий
|
||||
└── Валидационный DAG для самоконтроля
|
||||
|
||||
solution (полное решение)
|
||||
└── Все таблицы реализованы — эталон для самопроверки
|
||||
и подсказка, если студент застрял
|
||||
```
|
||||
|
||||
### Workflow студента
|
||||
|
||||
1. Форкает репозиторий
|
||||
2. Читает README и ТЗ
|
||||
3. `make up` — поднимает стенд
|
||||
4. `make bookings-init` — инициализирует источник
|
||||
5. Запускает DDL-DAG'и (эталонные таблицы создаются)
|
||||
6. Запускает ETL-DAG'и — эталонный срез работает
|
||||
7. Реализует задания из ТЗ (SQL + таски в DAG)
|
||||
8. Проверяет себя через валидационный DAG
|
||||
9. `make bookings-generate-day` — генерирует новый день, проверяет
|
||||
инкрементальность
|
||||
10. Защищает работу перед ментором
|
||||
|
||||
---
|
||||
|
||||
## 8. Критерии приёмки курсовой
|
||||
|
||||
### Для студента (самопроверка)
|
||||
|
||||
- [ ] Стенд поднимается (`make up`) без ошибок
|
||||
- [ ] Все DAG'и проходят без failed-тасков
|
||||
- [ ] Данные доезжают от STG до DM
|
||||
- [ ] Валидационный DAG проходит на всех реализованных таблицах
|
||||
- [ ] После `make bookings-generate-day` + повторного запуска DAG
|
||||
данные корректно доливаются (инкрементальность работает)
|
||||
|
||||
### Для ментора (ревью + защита)
|
||||
|
||||
- [ ] Код соответствует naming conventions (`docs/design/naming_conventions.md`)
|
||||
- [ ] SQL идемпотентен (повторный запуск не ломает данные)
|
||||
- [ ] Distribution keys выбраны осмысленно
|
||||
- [ ] Студент может объяснить: почему delete+insert, а не MERGE;
|
||||
разницу SCD1/SCD2; что такое HWM; как работает _load_id
|
||||
- [ ] Код оформлен для портфолио (чистый Git-history, README)
|
||||
|
||||
---
|
||||
|
||||
## 9. Ограничения и риски
|
||||
|
||||
| Риск / ограничение | Митигация |
|
||||
|--------------------------------------------|-------------------------------------------------|
|
||||
| Стенд тяжёлый (~8-16 GB RAM) | Указать минимальные требования; не утяжелять |
|
||||
| bookings-db генерирует данные медленно | Не добавлять нагрузку; задокументировать ожидание|
|
||||
| Студент может застрять надолго | Ветка `solution` как подсказка; еженедельные встречи |
|
||||
| Greenplum 6.x — устаревающая версия | Для учебных целей достаточно; паттерны переносимы |
|
||||
| PXF нестабилен при холодном старте | Задокументировано в README; healthcheck настроен |
|
||||
|
||||
### Требования к машине студента
|
||||
|
||||
- 2-4 CPU, 8-16 GB RAM, 25-40 GB диска
|
||||
- Linux / WSL2 / macOS
|
||||
- Docker + Docker Compose
|
||||
|
||||
---
|
||||
|
||||
## 10. План работ
|
||||
|
||||
План с чекбоксами и рекомендациями по инструментам: [TODO.md](../../TODO.md).
|
||||
|
||||
---
|
||||
|
||||
## 11. Открытые вопросы
|
||||
|
||||
1. **Название** — рабочее: «Greenplum Bookings DWH». Финализировать.
|
||||
@@ -1,173 +0,0 @@
|
||||
# Дизайн курсового задания
|
||||
|
||||
> Тактические решения по нарезке задания, порядку выполнения и самопроверке.
|
||||
> Стратегию и контекст см. в [PRD.md](PRD.md).
|
||||
|
||||
---
|
||||
|
||||
## 1. Эталонный срез: витрина `sales_report`
|
||||
|
||||
Эталоном выбрана витрина `dm.sales_report` и вся её цепочка вниз по слоям.
|
||||
|
||||
**Почему `sales_report`:**
|
||||
- Покрывает SCD1 (airports, tariffs), HWM-инкремент, fact load
|
||||
- Богатая денормализация — хороший образец для подражания
|
||||
- Средняя сложность — не пугает, но и не тривиальна
|
||||
|
||||
### Эталонные таблицы (даны студенту)
|
||||
|
||||
| Слой | Таблицы |
|
||||
|------|-----------------------------------------------------------------|
|
||||
| DM | `sales_report` |
|
||||
| DDS | `fact_flight_sales`, `dim_airports` (SCD1), `dim_tariffs` (SCD1), `dim_calendar` |
|
||||
| ODS | `bookings`, `tickets`, `segments`, `flights`, `boarding_passes`, `airports`, `routes` |
|
||||
| STG | весь слой: `bookings`, `tickets`, `segments`, `flights`, `boarding_passes`, `airports`, `airplanes`, `seats`, `routes` |
|
||||
|
||||
### Задание студенту
|
||||
|
||||
| Слой | Таблицы | Что нового для студента |
|
||||
|------|-------------------------------------------------------------------|--------------------------------------------------|
|
||||
| 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` | Разная сложность (от простой к сложной) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Рекомендуемый порядок выполнения
|
||||
|
||||
Студенту рекомендуется (но не обязательно) двигаться в таком порядке:
|
||||
|
||||
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 — самая сложная, пересчёт истории
|
||||
|
||||
Порядок выстроен от простого к сложному. Каждый шаг опирается на опыт
|
||||
предыдущего.
|
||||
|
||||
---
|
||||
|
||||
## 3. SCD2: подход «рецепт без готового SQL»
|
||||
|
||||
Реализация `dim_routes` (SCD2) — ключевой вызов курсовой. Студент делает это
|
||||
самостоятельно, но ТЗ содержит пошаговую подсказку:
|
||||
|
||||
1. Алгоритм SCD2 текстом (без SQL):
|
||||
- Вычисли `hashdiff` по набору атрибутов (атрибуты перечислены в ТЗ)
|
||||
- Найди строки, у которых `hashdiff` изменился
|
||||
- Закрой старую версию (`valid_to = текущая_дата`)
|
||||
- Вставь новую версию (`valid_from = текущая_дата`, `valid_to = NULL`)
|
||||
2. Формула hashdiff: `md5(concat_ws('|', field1, field2, ...))`
|
||||
3. Ссылка на `naming_conventions.md` (поля `valid_from`, `valid_to`, `hashdiff`)
|
||||
4. Напоминание: полуоткрытый интервал `[valid_from, valid_to)`
|
||||
5. Если застрял — ветка `solution`
|
||||
|
||||
Самостоятельная реализация — ключ к запоминанию. SCD2 — обязательный вопрос
|
||||
на собеседованиях DE, и студент должен уметь объяснить его на основе
|
||||
собственного опыта.
|
||||
|
||||
---
|
||||
|
||||
## 4. Валидационный DAG (`bookings_validate`)
|
||||
|
||||
Отдельный DAG для самопроверки студента. Запускается вручную в Airflow UI
|
||||
после реализации заданий. Таски сгруппированы по слоям — студент видит,
|
||||
где именно проблема. Дополнительный бонус — практика чтения логов Airflow.
|
||||
|
||||
### Примерная структура тасков
|
||||
|
||||
```
|
||||
bookings_validate
|
||||
├── validate_ods
|
||||
│ ├── check_ods_airplanes_rowcount (ODS >= STG по кол-ву уникальных BK)
|
||||
│ ├── check_ods_seats_rowcount
|
||||
│ └── check_ods_no_null_pks (PK not null)
|
||||
├── validate_dds
|
||||
│ ├── check_dim_airplanes_exists
|
||||
│ ├── check_dim_passengers_exists
|
||||
│ ├── check_dim_routes_scd2 (valid_from/valid_to корректны)
|
||||
│ └── check_dim_routes_no_gaps (нет «дыр» в версиях SCD2)
|
||||
└── validate_dm
|
||||
├── check_airport_traffic_exists
|
||||
├── check_monthly_overview_exists
|
||||
├── check_route_performance_exists
|
||||
└── check_passenger_loyalty_exists
|
||||
```
|
||||
|
||||
### Реализация
|
||||
|
||||
- `PostgresOperator` + SQL-скрипты в `sql/validate/`
|
||||
- Каждый SQL-скрипт выполняет SELECT и бросает исключение (через
|
||||
`DO $$ ... RAISE EXCEPTION ... $$`), если проверка не пройдена
|
||||
- Сообщения об ошибках — дружелюбные, с подсказкой что делать дальше
|
||||
|
||||
### Ключевые проверки
|
||||
|
||||
- Таблицы существуют и содержат данные
|
||||
- PK не содержат NULL
|
||||
- SCD2: `valid_to IS NULL` для текущих версий, нет перекрытий интервалов
|
||||
- Кросс-слойная консистентность (row count ODS vs STG)
|
||||
- DM-витрины содержат данные за загруженные дни
|
||||
|
||||
### Активная проверка SCD2 (`check_dim_routes_scd2`)
|
||||
|
||||
Справочник `bookings.routes` в демо-базе статичен — маршруты не меняются
|
||||
между запусками генератора. Поэтому при обычном прогоне пайплайна студент
|
||||
никогда не увидит, как SCD2 закрывает старую версию и создаёт новую.
|
||||
|
||||
Чтобы проверить корректность реализации, таск `check_dim_routes_scd2`
|
||||
должен быть **активным** (не только читать, но и тестировать загрузку):
|
||||
|
||||
1. Сохранить текущее состояние `ods.routes` и `dds.dim_routes` (temp-таблицы).
|
||||
2. Вставить в `ods.routes` тестовый маршрут с изменённым атрибутом
|
||||
(например, `scheduled_time` → `departure_time` сдвинут на 1 час).
|
||||
3. Вызвать студенческий SQL загрузки `dim_routes` (`sql/dds/dim_routes_load.sql`).
|
||||
4. Проверить результат:
|
||||
- Старая версия маршрута закрыта (`valid_to IS NOT NULL`).
|
||||
- Новая версия открыта (`valid_to IS NULL`, `hashdiff` отличается).
|
||||
- Нет «дыр» между `valid_to` старой и `valid_from` новой версии.
|
||||
5. Откатить изменения: восстановить `ods.routes` и `dds.dim_routes`
|
||||
из сохранённых temp-таблиц.
|
||||
|
||||
Это единственный способ гарантировать, что SCD2 работает, без мутации
|
||||
источника (что сломало бы генератор `continue()`).
|
||||
|
||||
---
|
||||
|
||||
## 5. Формат ТЗ от аналитика
|
||||
|
||||
Файл: `docs/assignment/analyst_spec.md` (или несколько файлов по слоям).
|
||||
|
||||
Для каждой таблицы-задания документ содержит:
|
||||
|
||||
- **Имя таблицы** и целевая схема (stg / ods / dds / dm)
|
||||
- **Описание** — что хранит таблица, бизнес-смысл
|
||||
- **Список полей** с типами и описанием
|
||||
- **Маппинг источников** — откуда берётся каждое поле
|
||||
- **Бизнес-правила и фильтры** (если есть)
|
||||
- **Тип историзации** (SCD1 / SCD2 / snapshot / append)
|
||||
- **Гранулярность** (одна строка = ?)
|
||||
- **Distribution key** (подсказка или задание на выбор)
|
||||
|
||||
Формат — приближен к реальным ТЗ, которые студент встретит на работе.
|
||||
|
||||
---
|
||||
|
||||
## 6. Бэклог: идеи для будущих итераций
|
||||
|
||||
### PXF-практикум (замена STG-заданий)
|
||||
|
||||
После переноса всего STG-слоя в эталон (см. `docs/plans/2026-03-11_routes-to-reference.md`)
|
||||
студенты не практикуются в создании PXF external tables и загрузке сырых данных.
|
||||
Это важный навык для DE — нужно компенсировать отдельным заданием.
|
||||
|
||||
Варианты:
|
||||
- **Новый источник данных**: подключить CSV/JSON-файл (например, справочник городов
|
||||
или курсов валют) через PXF и загрузить в отдельную STG-таблицу
|
||||
- **Мини-задание «подключи внешний справочник»**: студент создаёт PXF external table
|
||||
для существующей таблицы источника и сравнивает результат с эталонной STG
|
||||
- **Лабораторная работа**: отдельное упражнение на создание external table +
|
||||
сравнение форматов (TEXT vs CUSTOM), профилей PXF, обработку типов
|
||||
@@ -569,8 +569,9 @@ UPDATE факта обновляет только **мутабельные по
|
||||
1. Таблица не пуста
|
||||
2. Нет дублей по зерну `(ticket_no, flight_id)`
|
||||
3. Количество строк = `COUNT(*)` из `ods.segments`
|
||||
4. **Обязательные FK**: `passenger_sk IS NULL` = 0, `tariff_sk IS NULL` = 0
|
||||
5. **FK маршрута**: NULL в любом из `route_sk`, `departure_airport_sk`, `arrival_airport_sk`, `airplane_sk` — допустимо при аномалиях, считаем и логируем (`RAISE NOTICE`); фейлим если > 1% строк
|
||||
4. **Обязательные FK**: `tariff_sk IS NULL` = 0. На main `passenger_sk` — NOTICE (dim_passengers — заглушка); на solution — EXCEPTION.
|
||||
5. **Эталонные FK аэропортов**: `departure_airport_sk`, `arrival_airport_sk` (через `ods.routes`) — порог 1%, EXCEPTION.
|
||||
**Студенческие FK**: `route_sk`, `airplane_sk` — на main NOTICE (dim_routes — заглушка, 100% NULL допустимо); на solution — порог 1%, EXCEPTION.
|
||||
6. **Calendar**: `calendar_sk IS NULL` — допустимо если `scheduled_departure IS NULL` в ODS; считаем и логируем (`RAISE NOTICE`); фейлим если > 1% строк
|
||||
7. Обязательные поля: `book_ref`, `ticket_no`, `flight_id`, `is_boarded` не NULL
|
||||
|
||||
|
||||
@@ -512,7 +512,9 @@ ANALYZE ods.bookings;
|
||||
### 6.4. Поведение при пустом батче
|
||||
|
||||
- для инкрементальных таблиц (`bookings`, `tickets`, `flights`, `segments`, `boarding_passes`) пустой батч допустим;
|
||||
- для snapshot-справочников (`airports`, `airplanes`, `routes`, `seats`) пустой батч считаем ошибкой.
|
||||
- для snapshot-справочников (`airports`, `routes`) пустой батч считаем ошибкой.
|
||||
На main `airplanes` и `seats` — студенческие заглушки (load/dq = `SELECT 1;`),
|
||||
таблицы будут пустыми до реализации студентом.
|
||||
|
||||
---
|
||||
|
||||
@@ -531,7 +533,8 @@ ANALYZE ods.bookings;
|
||||
|
||||
3. **Обязательные поля** не `NULL`/не пустые.
|
||||
|
||||
4. **Батч не пустой** для snapshot-справочников (`airports`, `airplanes`, `routes`, `seats`): если STG-батч оказался пустым — это ошибка (источник недоступен или PXF не работает).
|
||||
4. **Батч не пустой** для эталонных snapshot-справочников (`airports`, `routes`): если STG-батч оказался пустым — это ошибка (источник недоступен или PXF не работает).
|
||||
На main `airplanes_dq.sql` и `seats_dq.sql` — студенческие заглушки.
|
||||
|
||||
5. **Ссылочная целостность** в ODS:
|
||||
- `tickets.book_ref -> bookings.book_ref`
|
||||
@@ -617,7 +620,8 @@ tests/test_dags_smoke.py (+ smoke для 2 новых DAG)
|
||||
resolve_stg_batch_id
|
||||
├-> load_ods_bookings -> dq_ods_bookings -> load_ods_tickets -> dq_ods_tickets ──────────────────┐
|
||||
├-> load_ods_airports -> dq_ods_airports ─┐ │
|
||||
├-> load_ods_airplanes -> dq_ods_airplanes ─┼-> load_ods_routes -> dq_ods_routes │
|
||||
├-> load_ods_airplanes -> dq_ods_airplanes ─┐
|
||||
│ ├-> load_ods_routes -> dq_ods_routes │
|
||||
└-> └-> load_ods_seats -> dq_ods_seats │
|
||||
│
|
||||
dq_ods_routes -> load_ods_flights -> dq_ods_flights │
|
||||
@@ -631,7 +635,8 @@ resolve_stg_batch_id
|
||||
|
||||
Зависимости (по FK):
|
||||
- `tickets` после `bookings` (FK: `book_ref`);
|
||||
- `routes` после `airports` и `airplanes` (FK: `departure_airport`, `arrival_airport`, `airplane_code`);
|
||||
- `routes` после `airports` (FK: `departure_airport`, `arrival_airport`).
|
||||
На ветке `solution` также зависит от `airplanes` (FK: `airplane_code`);
|
||||
- `seats` после `airplanes` (FK: `airplane_code`);
|
||||
- `flights` после `routes` (FK: `route_no`);
|
||||
- `segments` после `flights` и `tickets` (FK: `flight_id`, `ticket_no`);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 1. Цель и общий контур
|
||||
|
||||
- Источник: Postgres в контейнере `bookings-db`, база `demo`, таблица `bookings.bookings` (см. [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md)).
|
||||
- Источник: Postgres в контейнере `bookings-db`, база `demo`, таблица `bookings.bookings`.
|
||||
- Цель: показываем путь данных от операционной БД до сырого слоя DWH в Greenplum.
|
||||
- В этом документе описываем часть `src (bookings-db) → STG (Greenplum)`. STG — входной слой; далее данные обрабатываются в ODS → DDS → DM (см. соответствующие design-документы).
|
||||
|
||||
@@ -127,8 +127,7 @@ DDL определён в `sql/stg/bookings_ddl.sql` и подключается
|
||||
|
||||
## 5. Связь с остальными документами
|
||||
|
||||
- [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md) — как готовится и генерируется источник `bookings-db`.
|
||||
- [`docs/reference/pxf_bookings.md`](../reference/pxf_bookings.md) — детали настройки PXF и внешней таблицы для чтения из `bookings-db`.
|
||||
- Детали настройки PXF и часовых поясов — в ветке `solution` (`docs/reference/`).
|
||||
- `sql/stg/bookings_ddl.sql` — DDL для схемы `stg` и таблиц `stg.bookings_ext` / `stg.bookings` (подключается из `sql/ddl_gp.sql` и применяется через `make ddl-gp`).
|
||||
|
||||
Дальнейшая обработка данных описана в design-документах ODS/DDS/DM (см. раздел 5).
|
||||
|
||||
@@ -310,6 +310,5 @@ Degenerate keys: `book_ref`, `ticket_no`, `flight_id`, `book_date`, `seat_no`.
|
||||
- [`bookings_dds_design.md`](bookings_dds_design.md) — дизайн DDS (Star Schema, SCD2)
|
||||
- [`bookings_dm_design.md`](bookings_dm_design.md) — дизайн DM (5 витрин)
|
||||
- [`naming_conventions.md`](naming_conventions.md) — нейминг полей
|
||||
- [`../reference/bookings_tz.md`](../reference/bookings_tz.md) — часовые пояса
|
||||
- [`../reference/pxf_bookings.md`](../reference/pxf_bookings.md) — настройка PXF
|
||||
- Часовые пояса и настройка PXF — в ветке `solution` (`docs/reference/`)
|
||||
- [`../assignment/analyst_spec.md`](../assignment/analyst_spec.md) — ТЗ от аналитика (курсовое задание)
|
||||
|
||||
Reference in New Issue
Block a user