10 KiB
От карты к SQL загрузки
На карте найдите таблицу, которую хотите заполнить, и откройте ее SQL загрузки. Проследите, какие строки скрипт читает, что меняет и по какому ключу записывает результат. Смысл строк и связей разобран в руководстве о структуре DWH.
Для первого задания достаточно примера ods.airports ниже.
К сборке факта вернитесь перед заданиями DDS.
Адресные ссылки на карту работают в локальном просмотре;
если читаете в Gitea, используйте инструкцию открытия карты.
Справочник: stg.airports → ods.airports
Откройте ods.airports на карте
и связь Типизация и загрузка ODS.
Здесь один источник: stg.airports. В STG накапливаются снимки разных запусков,
а в ODS нужна одна строка на аэропорт из выбранного снимка.
Рядом откройте airports_load.sql. Пройдите скрипт по порядку:
-
TRUNCATE TABLE ods.airportsочищает предыдущий снимок. СледующийINSERTзаменяет его целиком, поэтому исчезнувший из нового снимка аэропорт исчезнет и из ODS. -
В CTE
srcнайдитеFROM stg.airportsи фильтр_load_id:WHERE s._load_id = '{{ ti.xcom_pull(task_ids="resolve_stg_batch_id") }}'::textЗадача
resolve_stg_batch_idв ODS DAG выбирает общий батч четырех справочников STG или беретstg_batch_idиз параметров запуска. Этот фильтр оставляет один снимок из истории STG. -
Выражения
airport_name::json->>'ru',city::json->>'ru'иcountry::json->>'ru'извлекают русские названия. Остальные бизнес-поля переносятся без преобразования. -
ROW_NUMBER()нумерует строки внутриairport_codeпо_load_ts DESC, затемevent_ts DESC NULLS LAST. ФинальныйWHERE s.rn = 1оставляет одну строку на код. -
Сопоставьте колонки
INSERT INTO ods.airports (...)с финальнымSELECT. В_load_idсохраняется идентификатор выбранного STG-батча, в_load_tsзаписывается время загрузки ODS. Поля и типы результата заданы в airports_ddl.sql. -
ANALYZEобновляет статистику таблицы для планировщика запросов. Проверки находятся отдельно: airports_dq.sql сравнивает множества ключей STG-батча и ODS, ищет дубли и пустые обязательные поля.
Повторная загрузка того же снимка должна сохранить бизнес-строки без дублей;
время _load_ts при этом обновится.
Теперь переходите к первой самостоятельной загрузке.
Факт: сегмент билета и его измерения
Откройте dds.fact_flight_sales
и fact_flight_sales_load.sql.
Одна строка факта соответствует паре (ticket_no, flight_id).
В примере поездки два билета с тремя
сегментами дают три строки факта.
Найдите источник новых строк
В файле сначала идет UPDATE, а затем CTE fact_src и INSERT.
Начните с fact_src: здесь виден полный набор источников новых строк.
FROM ods.segments AS seg задает зерно, а seg.amount AS price
переносит цену сегмента в факт.
Участок fact_src |
Что добавляется к сегменту | Связь на карте |
|---|---|---|
JOIN ods.tickets, затем JOIN ods.bookings |
Бронирование, пассажир и дата покупки | Билет и пассажир, дата бронирования |
JOIN ods.flights |
Дата вылета и номер маршрута | Рейс, дата и маршрут |
LEFT JOIN подзапроса из ods.routes |
Коды аэропортов из строки с наибольшим validity на route_no |
Коды двух аэропортов |
Два LEFT JOIN dds.dim_airports как dep и arr |
departure_airport_sk и arrival_airport_sk по двум кодам |
Вылет, прилет |
LEFT JOIN dds.dim_routes, затем dds.dim_airplanes |
Версия маршрута на дату рейса и SK ее модели самолета | Версия маршрута, модель |
LEFT JOIN dds.dim_calendar, dds.dim_tariffs, dds.dim_passengers |
SK по дате вылета, классу обслуживания и passenger_id |
Дата, тариф, пассажир |
LEFT JOIN ods.boarding_passes по обоим полям ключа |
seat_no; наличие талона задает is_boarded |
Посадка и место |
Если билет, бронирование или рейс не найдены, INNER JOIN исключит сегмент
из вставки. LEFT JOIN сохранит его при отсутствии совпадения: например,
без талона получатся seat_no = NULL и is_boarded = false.
Обратите внимание на два разных пути от маршрута:
- Аэропорты берутся через готовый
ods.routes. ОтборORDER BY validity DESCработает по полю TEXT и не использует дату рейса. route_skищется в студенческомdim_routesпо дате вылета в интервале[valid_from, valid_to). Из этой версии беретсяairplane_codeдля поискаairplane_sk.
До выполнения заданий route_sk, airplane_sk и passenger_sk могут быть
NULL. Путь аэропортов от студенческих измерений не зависит.
Объяснение этой части модели: аэропорты и версия маршрута.
Найдите запись результата
Финальный INSERT берет поля из fact_src. Условие NOT EXISTS
проверяет пару (ticket_no, flight_id) и пропускает уже записанные строки.
Вернитесь к UPDATE в начале файла: он меняет только цену, место,
признак посадки и метки загрузки у существующих строк.
Ключи измерений он не пересчитывает.
Поэтому после реализации измерений нужен пересчет факта по ТЗ. Проверки результата находятся в fact_flight_sales_dq.sql.
Как проверить свой слой
Перед записью SQL найдите свой объект на карте и откройте его пункт ТЗ.
Сформулируйте, что означает одна строка результата, по каким полям соединяются
источники и что произойдет при отсутствии совпадения. Затем сверяйте
INSERT с DDL, а преобразования и *_dq.sql с требованиями задания.
Близкие готовые примеры для следующих этапов:
- SCD1: dim_airports_load.sql обновляет
изменившиеся атрибуты через
IS DISTINCT FROMи вставляет новые бизнес-ключи. - DM: sales_report_load.sql находит
затронутые даты по
_load_tsфакта, пересчитывает за них полные агрегаты во временную таблицу и выполняетUPDATEиINSERT.
Порядок заданий ведет к требованиям каждого этапа. Имена служебных полей проверяйте по соглашениям, состав DQ - по справочнику проверок.