Руководства STG/ODS/DDS/DM сверены с действующими SQL и DAG, ожидания учебных заглушек связаны с ТЗ. Самопроверка заданий отделена от проверок разработки и исторических планов. Для dim_routes закреплено обновление описательных полей только у открытых версий. SQL, DAG, DDL и настройки стенда не менялись. Проверки: make lint; make test (4 passed, 14 skipped); карта; 292 локальные ссылки; маршрут чтения и карта в Chromium. Живой ETL не запускался.
9.9 KiB
Загрузка ODS → DDS: bookings_to_gp_dds
DAG наполняет измерения и собирает dds.fact_flight_sales.
Одна строка факта соответствует сегменту билета: (ticket_no, flight_id).
У одного билета может быть несколько таких строк.
Сборка показана на карте
и в разборе SQL.
Карту открывайте локально.
Перед запуском
Дождитесь успешных STG и ODS. Таблицы DDS должны быть созданы через
bookings_dds_ddl или общий make ddl-gp.
Затем в Airflow UI запустите bookings_to_gp_dds целиком.
DDS читает состояние ODS; передавать stg_batch_id ему не нужно.
| Объект | Что уже выполняется на main |
|---|---|
dim_calendar |
Заполнение датами с 2016-01-01 по 2030-12-31, только если таблица пуста |
dim_airports |
Обновление изменившихся атрибутов и вставка новых аэропортов с постоянными SK |
dim_tariffs |
Добавление новых классов обслуживания из ods.segments |
fact_flight_sales |
Обновление существующих сегментов и вставка новых пар (ticket_no, flight_id) |
dim_airplanes, dim_passengers, dim_routes |
Загрузки и DQ пока содержат SELECT 1;; требования находятся в части 2 ТЗ |
До выполнения заданий три студенческих измерения остаются пустыми.
Готовый факт при этом загружается: отсутствующие ключи измерений сохраняются
как NULL, чтобы можно было изучить цепочку до написания собственного SQL.
Порядок задач
В DAG сначала выполняется
load_dds_dim_calendar → dq_dds_dim_calendar. Затем:
- Параллельно могут загружаться
dim_airports,dim_airplanes,dim_tariffsиdim_passengers; у каждого измерения своя следующая DQ-задача. load_dds_dim_routesждетdq_dds_dim_airportsиdq_dds_dim_airplanes, затем выполняетсяdq_dds_dim_routes.load_dds_fact_flight_salesждет DQ всех пяти измерений после календаря.dq_dds_fact_flight_sales → finish_dds_summaryзавершают запуск.
Это порядок задач Airflow. Источники строк и поля соединений показаны на карте отдельно от него.
Как работают готовые загрузки
dim_calendar_load.sql проверяет
NOT EXISTS (SELECT 1 FROM dds.dim_calendar LIMIT 1). Если есть хотя бы одна
строка, скрипт не вставляет даты. Повторный запуск не пересоздает календарь
и не дополняет частично заполненную таблицу.
Его DQ проверяет также покрытие дат рейсов ODS.
dim_airports_load.sql сохраняет SK
существующего аэропорта, обновляет изменившиеся атрибуты через
IS DISTINCT FROM и вставляет новые бизнес-ключи.
dim_tariffs_load.sql только добавляет
недостающие значения fare_conditions.
Метки измененных строк относятся к текущему запуску DDS;
календарь не содержит _load_id и _load_ts.
В fact_flight_sales_load.sql есть две операции:
UPDATEменяет цену, место, признак посадки и метки загрузки, если эти бизнес-поля изменились. SK измерений остаются прежними.INSERTсобирает данные из ODS и измерений для пар(ticket_no, flight_id), которых еще нет в факте.
Факт не отбирает дельту по HWM. Скрипт читает ODS и сопоставляет бизнес-ключи с уже записанными строками.
Аэропорты вылета и прилета находятся через ods.routes → dim_airports.
Из ODS выбирается строка с наибольшим validity для route_no; сортировка
идет по TEXT, дата рейса в этом отборе не участвует.
route_sk определяется отдельно: по дате вылета в полуоткрытом интервале
[valid_from, valid_to) измерения dim_routes. Из найденной версии берется
код модели для поиска airplane_sk.
Разбор соединений показывает,
какие строки сохраняет LEFT JOIN и что происходит при отсутствии измерения.
Учебные измерения
Начните с моделей самолетов и пассажиров, затем переходите к версиям маршрута. Поля, hashdiff и алгоритм SCD2 определены в ТЗ.
У маршрута изменение версионируемых атрибутов создает новую строку.
Описательные поля из других измерений обновляются только у открытых версий
(valid_to IS NULL), без новой версии; закрытые версии сохраняют свои значения.
Это правило также записано в алгоритме ТЗ.
После реализации измерений выполните
пересчет факта и витрин.
Обычный повторный запуск DDS не заполнит SK в старых строках факта,
поскольку его UPDATE эти поля не меняет.
Проверка результата
В make gp-psql выполните:
SELECT COUNT(*) FROM dds.dim_calendar;
SELECT COUNT(*) FROM dds.dim_airports;
SELECT COUNT(*) FROM dds.dim_tariffs;
SELECT
(SELECT COUNT(*) FROM dds.fact_flight_sales) AS fact_rows,
(SELECT COUNT(*) FROM ods.segments) AS segment_rows;
SELECT ticket_no, flight_id, departure_airport_sk, arrival_airport_sk,
route_sk, airplane_sk, passenger_sk, price, is_boarded
FROM dds.fact_flight_sales
ORDER BY ticket_no, flight_id
LIMIT 10;
На подготовленном стенде готовые измерения и факт непусты.
fact_rows должен точно совпасть с segment_rows.
Готовая DQ факта также ищет дубли
по паре ключей и проверяет обязательные поля.
На учебной ветке NULL в passenger_sk, route_sk и airplane_sk
вызывает только NOTICE. NULL в tariff_sk вызывает ошибку;
для строк с отсутствующим аэропортом и для calendar_sk допустима доля
не выше 1%. Эти послабления не заменяют проверку заполнения ключей после задания.
Свои *_dq.sql реализуйте по ТЗ и
справочнику DQ. Для дополнительной проверки DDS
используйте validate_dds в bookings_validate, соблюдая
порядок запуска и восстановления.
Далее переходите к DM.
Если загрузка не прошла
- Нет
dds.*: выполнитеbookings_dds_ddl. - DQ календаря сообщает о непокрытых датах: сравните даты вылета ODS
с диапазоном и содержимым
dim_calendar. Повторный запуск загрузки непустого календаря не заполнит пропуски. - Число строк факта отличается от ODS: проверьте ключи билета, бронирования
и рейса, затем соединения в
fact_src. Потеря строки наINNER JOINи размножение строк из-за нескольких подходящих версий дают разные причины одного расхождения. - Ошибка в вашей DQ маршрутов: проверьте открытые версии, интервалы и hashdiff
по ТЗ. Успешная заглушка
SELECT 1;этих свойств не проверяет.