Перейти к основному содержимому

Средний уровень: Шаги трансформации, созданные для определенных целей

Как только наши атомы готовы к работе, мы приступим к их объединению в более сложные, связанные молекулярные формы. Средний уровень — это место, где живут эти молекулы, создавая разнообразные формы с конкретными целями на пути к более сложным белкам и клеткам, которые мы будем использовать для оживления наших продуктов данных.

Средний уровень: Файлы и папки

Давайте рассмотрим средний уровень нашего проекта, чтобы более конкретно понять цель этого этапа.

models/intermediate
└── finance
├── _int_finance__models.yml
└── int_payments_pivoted_to_orders.sql
  • Папки
    • ✅ Подкаталоги на основе бизнес-группировок. Подобно уровню подготовки, мы разместим этот уровень моделей внутри их собственной подкаталога intermediate. В отличие от уровня подготовки, здесь мы переходим к бизнес-конформности, разделяя наши модели на подкаталоги не по их исходной системе, а по их области бизнес-задач.
  • Имена файлов
    • ✅ int_[entity]s_[verb]s.sql - разнообразие трансформаций, которые могут происходить на среднем уровне, делает сложным строгое определение их имен. Лучший принцип — думать о глаголах (например, pivoted, aggregated_to_user, joined, fanned_out_by_quantity, funnel_created и т.д.) на среднем уровне. В нашем примере проекта мы используем промежуточную модель для поворота платежей к зерну заказа, поэтому называем нашу модель int_payments_pivoted_to_orders. Это позволяет любому быстро понять, что происходит в этой модели, даже если они не знают SQL. Эта ясность стоит длинного имени файла. Важно отметить, что на этом уровне мы убрали двойные подчеркивания. Переходя к бизнес-конформным концепциям, нам больше не нужно разделять систему и сущность и просто ссылаться на объединенную сущность, если это возможно. В случаях, когда вам нужны промежуточные модели для работы на уровне исходной системы (например, int_shopify__orders_summed, int_core__orders_summed, которые вы позже объедините), вы сохраните двойные подчеркивания. Некоторые люди предпочитают также разделять сущность и глаголы двойными подчеркиваниями. Это вопрос предпочтений, но в нашем опыте часто существует внутренняя связь между сущностями и глаголами на этом уровне, что делает это трудным для поддержания.
Не оптимизируйте слишком рано!

Пример проекта очень прост для иллюстративных целей. Такой уровень разделения в наших пост-стейджинговых слоях, вероятно, не нужен при работе с таким небольшим количеством моделей. Помните, наша цель — единый источник правды. Мы не хотим, чтобы финансы и маркетинг работали с отдельными моделями orders, мы хотим использовать наш проект dbt как средство для объединения этих определений! Поэтому не разделяйте и не оптимизируйте слишком рано. Если у вас меньше 10 моделей marts и нет проблем с их разработкой и использованием, можете полностью отказаться от подкаталогов (кроме уровня подготовки, где вы всегда должны их реализовывать, добавляя новые исходные системы в ваш проект), пока проект не вырастет до такой степени, что они действительно понадобятся. Использование dbt всегда связано с упрощением сложности.

Средний уровень: Модели

Ниже приведена единственная промежуточная модель из нашего небольшого примерного проекта. Она является отличным примером использования в соответствии с описанными выше принципами, поскольку выполняет одну чётко определённую задачу: группировку и поворот (pivot) staging-модели к другому уровню детализации (grain). В ней используется немного Jinja, чтобы сделать модель более DRY (стремление к DRY относится не только к трансформациям по всему кодовой базе, но и к коду, который мы пишем внутри одного отдельного модели), однако не стоит пугаться, если вы пока не чувствуете себя уверенно с Jinja.

Глядя на имя CTEpivot_and_aggregate_payments_to_order_grain — мы получаем совершенно чёткое представление о том, что происходит внутри этого блока. Благодаря описательному именованию трансформаций внутри наших CTE в модели, так же как мы делаем это с файлами и папками, даже стейкхолдер, не знающий SQL, сможет понять назначение этого раздела, пусть и не сам код. По мере того как вы начнёте писать более сложные трансформации, выходя за пределы staging-слоя, держите эту идею в уме. Точно так же, как наши модели соединяются в DAG и рассказывают историю трансформаций на макроуровне, CTE могут делать то же самое на более мелком уровне — внутри файлов моделей.

-- int_payments_pivoted_to_orders.sql

{%- set payment_methods = ['bank_transfer','credit_card','coupon','gift_card'] -%}

with

payments as (

select * from {{ ref('stg_stripe__payments') }}

),

pivot_and_aggregate_payments_to_order_grain as (

select
order_id,
{% for payment_method in payment_methods -%}

sum(
case
when payment_method = '{{ payment_method }}' and
status = 'success'
then amount
else 0
end
) as {{ payment_method }}_amount,

{%- endfor %}
sum(case when status = 'success' then amount end) as total_amount

from payments

group by 1

)

select * from pivot_and_aggregate_payments_to_order_grain
  • ❌ Доступны конечным пользователям. Промежуточные модели, как правило, не должны быть доступны в основной производственной схеме. Они не предназначены для вывода на конечные цели, такие как панели управления или приложения, поэтому лучше держать их отдельно от моделей, которые таковыми являются, чтобы вы могли легче контролировать управление данными и их обнаружение.
  • ✅ Материализованы эфемерно. Учитывая вышеизложенное, одним из популярных вариантов является по умолчанию материализация промежуточных моделей эфемерно. Это, как правило, лучшее место для начала с точки зрения простоты. Это позволит избежать ненужных моделей в вашем хранилище с минимальной конфигурацией. Однако имейте в виду, что простота эфемерных моделей несколько усложняет отладку, так как они интерполируются в модели, которые их ref, а не существуют сами по себе, чтобы вы могли просмотреть их вывод.
  • ✅ Материализованы как представления в пользовательской схеме с особыми разрешениями. Более надежным вариантом является материализация ваших промежуточных моделей как представлений в определенной пользовательской схеме, вне вашей основной производственной схемы. Это дает вам дополнительное понимание разработки и упрощает отладку по мере увеличения количества и сложности ваших моделей, оставаясь при этом легким в реализации и занимая незначительное пространство.
Держите хранилище в порядке!

Существует три интерфейса к графу организационных знаний, который мы кодируем в dbt и в структуре папок нашего кодового репозитория, а также к результатам, которые попадают в хранилище. Поэтому крайне важно подходить к этим результатам осознанно. Думайте о схемах, таблицах и представлениях, которые вы создаёте в хранилище, как о части пользовательского опыта (UX), наравне с дашбордами, ML‑моделями, приложениями и другими сценариями использования данных, на которые вы ориентируетесь. Ключевую роль здесь играет то, насколько грамотно именованы и сгруппированы результаты, а также то, что модели, не предназначенные для широкого использования, либо не материализуются вовсе, либо размещаются в специальных областях с ограниченными правами доступа.

:::

  • Цели промежуточных моделей, поскольку они служат для разделения сложности наших моделей marts, могут принимать столько форм, сколько может потребовать трансформация данных. Некоторые из наиболее распространенных случаев использования промежуточных моделей включают:

    • ✅ Структурное упрощение. Объединение разумного количества (обычно от 4 до 6) сущностей или концепций (моделей подготовки или, возможно, других промежуточных моделей), которые будут объединены с другой аналогично предназначенной промежуточной моделью для создания марта — вместо того, чтобы иметь 10 соединений в нашем марте, мы можем соединить две промежуточные модели, каждая из которых содержит часть сложности, что дает нам повышенную читаемость, гибкость, поверхность тестирования и понимание наших компонентов.
    • ✅ Изменение зерна. Промежуточные модели часто используются для расширения или сжатия моделей до правильного составного зерна — если мы строим март для order_items, который требует от нас расширения наших orders на основе столбца quantity, создавая новую единую строку для каждого элемента, это было бы идеально сделать в конкретной промежуточной модели, чтобы сохранить ясность в нашем марте и легче увидеть, что наше зерно правильно, прежде чем мы смешаем его с другими компонентами.
    • ✅ Изоляция сложных операций. Полезно перемещать любые особенно сложные или трудные для понимания части логики в их собственные промежуточные модели. Это не только упрощает их доработку и отладку, но и упрощает последующие модели, которые могут ссылаться на эту концепцию более четко читаемым образом. Например, в примере с расширением quantity, мы выигрываем, изолируя эту сложную часть логики, чтобы мы могли быстро отладить и тщательно протестировать эту трансформацию, а модели ниже по потоку могут ссылаться на order_items так, что это интуитивно легко понять.
Сужайте DAG, расширяйте таблицы.

Пока мы не дойдем до уровня marts и не начнем строить наши различные выводы, мы в идеале хотим, чтобы наш DAG выглядел как наконечник стрелы, направленный вправо. По мере того, как мы переходим от соответствия источнику к соответствию бизнесу, мы также переходим от многочисленных, узких, изолированных концепций к меньшему количеству, более широких, объединенных концепций. Мы объединяем наши компоненты в более широкие, более богатые концепции, и это создает эту форму в нашем DAG. Таким образом, когда мы дойдем до уровня marts, у нас будет надежный набор компонентов, которые можно быстро и легко настроить в любую конфигурацию, чтобы ответить на различные вопросы и удовлетворить конкретные потребности. Одно из правил, чтобы убедиться, что вы следуете этому шаблону на уровне отдельной модели, — это разрешать несколько входов в модель, но не несколько выходов. Несколько стрелок, входящих в наши пост-стейджинговые модели, — это здорово и ожидаемо, несколько стрелок, выходящих — это тревожный сигнал. Безусловно, есть ситуации, когда вам нужно нарушить это правило, но это то, о чем нужно знать, быть осторожным и избегать, когда это возможно.

Нашли ошибку?

0
Loading