Проработка задачи на ETL
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
# Дизайн STG для bookings в Greenplum (черновик)
|
||||
|
||||
_Внутренний документ для учебного стенда. Перед итоговой сдачей можно объединить с основной документацией._
|
||||
|
||||
## 1. Цель и общий контур
|
||||
|
||||
- Источник: Postgres в контейнере `bookings-db`, база `demo`, таблица `bookings.bookings` (см. `docs/internal/bookings_tz.md`).
|
||||
- Цель: показываем путь данных от операционной БД до сырого слоя DWH в Greenplum.
|
||||
- В этом документе описываем только часть `src (bookings-db) → STG (Greenplum)`. Слои ODS/DDS/DM студент проектирует сам по статье про моделирование DWH.
|
||||
|
||||
Логика на уровне слоёв (по статье):
|
||||
|
||||
- `src`: оперативная система (`bookings-db`, схема `bookings`).
|
||||
- `stg`: сырой слой в Greenplum, максимально близкий к источнику, без бизнес‑логики.
|
||||
- дальше по заданию менти можно строить `ods`/`dds`/`dm` поверх STG.
|
||||
|
||||
## 2. Схема и таблицы в Greenplum
|
||||
|
||||
### 2.1. Схема
|
||||
|
||||
- Используем одну схему `stg` в Greenplum.
|
||||
- В этой схеме будут:
|
||||
- внешняя таблица PXF для чтения из `bookings-db`;
|
||||
- внутренняя таблица STG для долговременного хранения «сырых» данных.
|
||||
|
||||
### 2.2. Внешняя таблица (PXF)
|
||||
|
||||
- Имя таблицы: `stg.bookings_ext`.
|
||||
- Назначение: «окно» в исходную таблицу `bookings.bookings` в `bookings-db` через PXF (JDBC).
|
||||
- Типы колонок:
|
||||
- можем использовать «родные» типы из `bookings.bookings` (включая даты/числа);
|
||||
- задача внешней таблицы — корректно читать данные из источника, не заниматься приведением типов.
|
||||
|
||||
DDL будет добавлен в `sql/ddl_gp.sql` в блоке DDL для Greenplum (примерно по шаблону из `docs/internal/pxf_bookings.md`), с `LOCATION ('pxf://bookings.bookings?PROFILE=JDBC&SERVER=bookings-db')`.
|
||||
|
||||
### 2.3. Внутренняя таблица STG
|
||||
|
||||
- Имя таблицы: `stg.bookings`.
|
||||
- Назначение: хранить сырые данные из источника для последующей обработки (ODS/DDS/витрины).
|
||||
- Принципы моделирования:
|
||||
- все бизнес‑колонки из `bookings.bookings` храним как `TEXT` (как в примерах STG из статьи);
|
||||
- не делаем `UPDATE/DELETE`, только `INSERT` новых записей;
|
||||
- бизнес‑колонки по названию совпадают с источником (чтобы проще было маппить).
|
||||
|
||||
Технологические колонки:
|
||||
|
||||
- `src_created_at_ts TIMESTAMP` — дата/время из источника, приведённая к TIMESTAMP:
|
||||
- используется как опорная колонка для инкрементальной загрузки;
|
||||
- заполняется из исходной даты/времени (`created_at` или аналог).
|
||||
- `load_dttm TIMESTAMP NOT NULL DEFAULT now()` — когда запись была загружена в STG.
|
||||
- `batch_id TEXT NOT NULL` — идентификатор «пачки» (например, `{{ ds_nodash }}` или `run_id` Airflow).
|
||||
- при необходимости позже можно добавить `src_system TEXT`, если появятся другие источники.
|
||||
|
||||
Колонки‑бизнес‑ключи (`booking_id` и т.п.) храним как `TEXT`. В слое DDS позже можно будет ввести суррогатные ключи и нормализовать модель под витрины.
|
||||
|
||||
## 3. Инкрементальная загрузка
|
||||
|
||||
### 3.1. Опорное поле для инкремента
|
||||
|
||||
- Опорная колонка: `src_created_at_ts` (внутреннее имя в STG).
|
||||
- Источник значения:
|
||||
- берём из соответствующей колонки в `bookings.bookings` (например, `book_date`/`created_at` — будет уточнено при реализации);
|
||||
- при чтении через `stg.bookings_ext` приводим к `TIMESTAMP`.
|
||||
|
||||
### 3.2. Правила определения full/delta
|
||||
|
||||
- При первом запуске, если таблица `stg.bookings` пуста:
|
||||
- считаем режим `full` — загружаем все строки из `stg.bookings_ext`.
|
||||
- При последующих запусках:
|
||||
- читаем `max(src_created_at_ts)` из `stg.bookings` за все предыдущие загрузки;
|
||||
- считаем, что нужно загрузить только строки, где `src_created_at_ts` больше этой максимальной метки и не позже конца текущего учебного дня.
|
||||
|
||||
Таким образом, вся логика инкремента «замкнута» на один техно‑столбец `src_created_at_ts`, который студент потом сможет использовать и на следующих слоях (например, в CDC‑логике).
|
||||
|
||||
## 4. DAG’и Airflow (логика на уровне задач)
|
||||
|
||||
### 4.1. DAG для DDL
|
||||
|
||||
- `dag_id`: `bookings_stg_ddl` (рабочее имя).
|
||||
- Назначение: один раз (или при изменении схемы) создать необходимые объекты в Greenplum:
|
||||
- схему `stg` (если её ещё нет);
|
||||
- внешнюю таблицу `stg.bookings_ext` (PXF → `bookings-db`);
|
||||
- внутреннюю таблицу `stg.bookings` с текстовыми колонками и тех.полями.
|
||||
- Этот DAG не загружает данные, только подготавливает структуру.
|
||||
- Вся DDL‑логика (CREATE/ALTER/DROP) сосредоточена здесь; рабочие DAG’и занимаются только DML (INSERT/SELECT).
|
||||
|
||||
### 4.2. DAG для ежедневной загрузки
|
||||
|
||||
- `dag_id`: `bookings_to_gp_stage` (рабочее имя).
|
||||
- Основные параметры:
|
||||
- `load_date` (по умолчанию `{{ ds }}`) — учебный день, за который генерим и грузим данные.
|
||||
- подключения:
|
||||
- `bookings_db_conn_id` — Airflow connection к `bookings-db`;
|
||||
- `greenplum_conn_id` — Airflow connection к Greenplum.
|
||||
|
||||
Предлагаемая последовательность задач:
|
||||
|
||||
1. `generate_bookings_day`
|
||||
- при необходимости создаёт таблицу `bookings.bookings` в `bookings-db` (одноразово);
|
||||
- **идемпотентность**: проверяет, есть ли данные за `load_date` в `bookings.bookings`;
|
||||
- если нет — генерирует данные за один учебный день (можно опираться на `make bookings-generate-day` и логику из `docs/internal/bookings_tz.md`);
|
||||
- если да — ничего не делает, логирует «данные за этот день уже есть» и считается успешно выполненной.
|
||||
2. `get_last_loaded_ts_from_gp`
|
||||
- читает `max(src_created_at_ts)` из `stg.bookings`;
|
||||
- если данных нет — возвращает `None` и режим загрузки `full`;
|
||||
- результат (последняя метка и режим) передаёт через XCom.
|
||||
3. `extract_and_load_increment_via_pxf`
|
||||
- делает `INSERT INTO stg.bookings (...) SELECT ... FROM stg.bookings_ext WHERE src_created_at_ts > :last_ts AND src_created_at_ts <= :window_end`;
|
||||
- в режиме `full` подставляет «минимальную» дату (или просто не фильтрует);
|
||||
- заполняет `src_created_at_ts`, `load_dttm`, `batch_id`.
|
||||
4. `check_row_counts`
|
||||
- сравнивает количество строк, прочитанных из `stg.bookings_ext`, и количеством реально вставленных в `stg.bookings`;
|
||||
- при расхождении падает с понятным сообщением «что посмотреть/проверить».
|
||||
5. (опционально) `finish_summary`
|
||||
- логирует итог: режим загрузки (full/delta), интервал `src_created_at_ts`, количество строк.
|
||||
|
||||
Эта последовательность служит учебным примером для менти: от генерации «операционных» данных до инкремента в сырой слой DWH.
|
||||
|
||||
## 5. Связь с остальными документами
|
||||
|
||||
- `docs/internal/bookings_tz.md` — как готовится и генерируется источник `bookings-db`.
|
||||
- `docs/internal/pxf_bookings.md` — детали настройки PXF и внешней таблицы для чтения из `bookings-db`.
|
||||
- `sql/ddl_gp.sql` — итоговый DDL для схемы `stg` и таблиц `stg.bookings_ext` / `stg.bookings` (применяется через `make ddl-gp`).
|
||||
|
||||
Дальнейшая модель DWH (слои ODS/DDS/DM, факт/измерения, SCD) должна быть спроектирована студентом по статье о моделировании данных, используя `stg.bookings` как входной слой.
|
||||
|
||||
Reference in New Issue
Block a user