Files
airflow-greenplum/docs/design/reading_the_pipeline.md
T

10 KiB
Raw Blame History

От карты к SQL загрузки

На карте найдите таблицу, которую хотите заполнить, и откройте ее SQL загрузки. Проследите, какие строки скрипт читает, что меняет и по какому ключу записывает результат. Смысл строк и связей разобран в руководстве о структуре DWH.

Для первого задания достаточно примера ods.airports ниже. К сборке факта вернитесь перед заданиями DDS. Адресные ссылки на карту работают в локальном просмотре; если читаете в Gitea, используйте инструкцию открытия карты.

Справочник: stg.airports → ods.airports

Откройте ods.airports на карте и связь Типизация и загрузка ODS. Здесь один источник: stg.airports. В STG накапливаются снимки разных запусков, а в ODS нужна одна строка на аэропорт из выбранного снимка.

Рядом откройте airports_load.sql. Пройдите скрипт по порядку:

  1. TRUNCATE TABLE ods.airports очищает предыдущий снимок. Следующий INSERT заменяет его целиком, поэтому исчезнувший из нового снимка аэропорт исчезнет и из ODS.

  2. В 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.

  3. Выражения airport_name::json->>'ru', city::json->>'ru' и country::json->>'ru' извлекают русские названия. Остальные бизнес-поля переносятся без преобразования.

  4. ROW_NUMBER() нумерует строки внутри airport_code по _load_ts DESC, затем event_ts DESC NULLS LAST. Финальный WHERE s.rn = 1 оставляет одну строку на код.

  5. Сопоставьте колонки INSERT INTO ods.airports (...) с финальным SELECT. В _load_id сохраняется идентификатор выбранного STG-батча, в _load_ts записывается время загрузки ODS. Поля и типы результата заданы в airports_ddl.sql.

  6. 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 - по справочнику проверок.