Остальная часть проекта
Обзор структуры проекта
До сих пор мы сосредотачивались на папке models, основном каталоге нашего dbt проекта. Далее мы расширим наш обзор и посмотрим, как остальные файлы и папки проекта вписываются в эту структуру, начиная с подхода к YAML конфигурационным файлам.
models
├── intermediate
│ └── finance
│ ├── _int_finance__models.yml
│ └── int_payments_pivoted_to_orders.sql
├── marts
│ ├── finance
│ │ ├── _finance__models.yml
│ │ ├── orders.sql
│ │ └── payments.sql
│ └── marketing
│ ├── _marketing__models.yml
│ └── customers.sql
├── staging
│ ├── jaffle_shop
│ │ ├── _jaffle_shop__docs.md
│ │ ├── _jaffle_shop__models.yml
│ │ ├── _jaffle_shop__sources.yml
│ │ ├── base
│ │ │ ├── base_jaffle_shop__customers.sql
│ │ │ └── base_jaffle_shop__deleted_customers.sql
│ │ ├── stg_jaffle_shop__customers.sql
│ │ └── stg_jaffle_shop__orders.sql
│ └── stripe
│ ├── _stripe__models.yml
│ ├── _stripe__sources.yml
│ └── stg_stripe__payments.sql
└── utilities
└── all_dates.sql
Подробности о YAML
При организации ваших YAML конфигурационных файлов в dbt проекте, вы должны сбалансировать централизацию и размер файлов, чтобы сделать конкретные конфигурации как можно более легкими для поиска. Важно отметить, что в то время как YAML файлы верхнего уровня (dbt_project.yml, packages.yml) должны иметь определенные имена и находиться в определенных местах, файлы, содержащие ваши словари sources и models, могут быть названы, расположены и организованы как угодно. Здесь важны внутренние содержимое. Таким образом, мы изложим нашу основную рекомендацию, а также плюсы и минусы популярной альтернативы. Как и во многих других аспектах организации вашего dbt проекта, здесь наиболее важны последовательность, ясное намерение и тщательная документация о том, как и почему вы делаете то, что делаете.
- ✅ Конфигурация на уровне папки. Как в примере выше, создавайте файл
_[directory]__models.ymlдля каждой папки в каталогеmodels, который настраивает все модели в этой папке. Для staging‑папок также добавляйте файл_[directory]__sources.ymlна каждую папку.- Ведущее подчёркивание гарантирует, что ваши YAML‑файлы будут сортироваться в начало каждой папки, что упрощает их отделение от файлов моделей.
- YAML‑файлам не требуются уникальные имена так же строго, как SQL‑файлам моделей, однако включение имени папки (вместо простого
_sources.ymlв каждой папке) позволяет быстрее находить нужный файл через fuzzy‑поиск. - За последние годы мы рекомендовали несколько разных соглашений об именовании, в том числе совсем недавно называли эти файлы
schema.yml. Мы упростили рекомендации и советуем называть файлы просто по словарю YAML, который они содержат. - Если вы используете doc blocks в своём проекте, мы рекомендуем придерживаться того же подхода и создавать markdown‑файл
_[directory]__docs.mdдля каждой папки, содержащий все doc blocks для моделей в этой папке.
- ❌ Конфигурация на уровне проекта. Некоторые помещают все YAML‑описания источников и моделей в один файл. Технически это возможно и действительно упрощает понимание того, в каком файле находится нужная конфигурация (поскольку файл всего один), но при этом становится гораздо сложнее находить конкретные настройки внутри этого файла. Мы рекомендуем находить баланс между этими двумя соображениями.
- ⚠️ Конфигурация на уровне модели. С другой стороны спектра, некоторые предпочитают создавать по одному YAML‑файлу на модель. Это менее проблематично, чем один монолитный файл, так как можно быстро искать файлы, точно знать, где находятся конкретные настройки, видеть модели без конфигураций (а значит, без тестов), просто глядя на дерево файлов, и получать ряд других преимуществ. Однако, по нашему мнению, дополнительное количество файлов, вкладок и окон, которые приходится создавать, копировать, вставлять, закрывать, открывать и администрировать, приводит к несколько более медленному процессу разработки, и этот недостаток перевешивает преимущества. Для большинства проектов конфигурация на уровне папки — самый сбалансированный подход, но если у вас есть веские причины использовать конфигурацию на уровне модели, существуют отличные проекты, которые успешно следуют этой парадигме.
- ✅ Каскадирование конфигураций. Используйте
dbt_project.ymlдля задания конфигураций по умолчанию на уровне папок. Применяйте хорошо организованную структуру каталогов, которую мы уже создали, чтобы определить базовые схемы и материализации, а затем используйте приоритет областей видимости dbt для задания отклонений от этих значений. Например, как показано ниже, задайте materializationtableпо умолчанию для marts, определите отдельные схемы для разных подпапок, а модели, которым требуется materializationincremental, можно настроить на уровне конкретной модели.
-- dbt_project.yml
models:
jaffle_shop:
staging:
+materialized: view
intermediate:
+materialized: ephemeral
marts:
+materialized: table
finance:
+schema: finance
marketing:
+schema: marketing
Одно из многих преимуществ этого последовательного подхода к структуре проекта заключается в возможности каскадного применения поведения по умолчанию. Тщательная организация наших папок и определение конфигурации на этом уровне, когда это возможно, освобождает нас от необходимости конфигурировать такие вещи, как схема и материализация, в каждой отдельной модели (не очень DRY!) — нам нужно только конфигурировать исключения из наших общих правил. Тегирование — это еще одна область, где этот принцип вступает в игру. Многие новички в dbt будут полагаться на теги, а не на строгую структуру папок, и быстро окажутся в ситуации, когда каждая модель требует тега. Это создает ненужную сложность. Мы хотим полагаться на наши папки как на основные селекторы и механизм группировки, и использовать теги для определения групп, которые являются исключениями. Выбор на основе папок, такой как **dbt build --select marts.marketing, гораздо проще, чем попытка тегировать каждую модель, связанную с маркетингом, надеясь, что все разработчики помнят добавить этот тег для новых моделей, и использование dbt build --select tag:marketing.
Определение групп
Группа — это набор узлов внутри DAG dbt. Группы позволяют выстраивать осознанное взаимодействие внутри команд и между командами, ограничивая доступ к приватным моделям.
Группы определяются в .yml‑файлах и указываются внутри ключа groups:.
Дополнительную информацию об использовании групп см. в разделе Добавление групп в ваш DAG.
Как мы используем другие папки
jaffle_shop
├── analyses
├── seeds
│ └── employees.csv
├── macros
│ ├── _macros.yml
│ └── cents_to_dollars.sql
├── snapshots
└── tests
└── assert_positive_value_for_total_amount.sql
До сих пор мы сосредотачивались в основном на основной области действия в нашем dbt проекте, папке models. Однако, как вы, вероятно, заметили, в нашем проекте есть несколько других папок. Хотя они, по замыслу, очень гибкие для ваших нужд, мы обсудим наиболее распространенные случаи использования этих других папок, чтобы помочь вам начать.
- ✅
seedsдля справочных (lookup) таблиц. Самый распространённый сценарий использования seeds — загрузка справочных таблиц, которые полезны для моделирования, но не существуют ни в одной исходной системе. Например, сопоставление почтовых индексов штатам или UTM‑параметров маркетинговым кампаниям. В этом примерном проекте у нас есть небольшой seed, который сопоставляет сотрудников с ихcustomer_id, чтобы мы могли обрабатывать их покупки с помощью специальной логики. - ❌
seedsдля загрузки исходных данных. Не используйте seeds для загрузки данных из исходной системы в хранилище. Если данные существуют в системе, к которой у вас есть доступ, их следует загружать с помощью полноценного EL‑инструмента в зону сырых данных (raw data) вашего хранилища. dbt предназначен для работы с данными уже в хранилище, а не как инструмент загрузки данных. - ✅
analysesдля хранения аудиторских запросов. Папкаanalysesпозволяет хранить любые запросы, в которых вы хотите использовать Jinja и контроль версий, но которые не должны собираться в виде моделей в хранилище. Возможностей здесь практически неограниченно, однако самый частый сценарий, который мы используем при настройке проектов в dbt Labs, — это хранение запросов, использующих пакет audit helper. Этот пакет чрезвычайно полезен для поиска расхождений в результатах при переносе логики из другой системы в dbt. - ✅
testsдля одновременного тестирования нескольких конкретных таблиц. По мере эволюции dbt‑тестов необходимость в написании singular‑тестов становилась всё меньше. Они по‑прежнему очень полезны для совместной проработки логики тестирования, но чаще всего вы либо перенесёте эту логику в собственные кастомные generic‑тесты, либо найдёте готовый тест, который подходит под ваши требования, в постоянно растущей экосистеме пакетов dbt (между дополнительными тестами вdbt-utilsиdbt-expectationsпокрыта почти любая ситуация). Тем не менее, одна область, где singular‑тесты по‑прежнему особенно полезны, — это гибкое тестирование сценариев, которые затрагивают несколько конкретных моделей. Если вам знакома разница между unit tests и integration tests (ещё) в разработке ПО, то generic‑ и singular‑тесты можно рассматривать аналогичным образом. Если вам нужно проверить результаты того, как несколько конкретных моделей взаимодействуют или соотносятся друг с другом, singular‑тест, скорее всего, будет самым быстрым способом зафиксировать нужную логику. - ✅
snapshotsдля создания записей медленно изменяющихся измерений типа 2 из исходных данных типа 1, которые обновляются деструктивно. Эта тема подробно описана в документации dbt. В отличие от других папок,snapshotsимеет более чётко определённое назначение; она выходит за рамки данного руководства, но упомянута здесь для полноты. - ✅
macrosдля устранения повторений (DRY) в трансформациях, которые вы выполняете снова и снова. Как и в случае со snapshots, подробное погружение в macros выходит за рамки этого руководства и хорошо описано в другом разделе. Однако одна важная рекомендация, связанная со структурой проекта, — писать документацию для ваших macros. Мы рекомендуем создавать файл_macros.ymlи документировать назначение и аргументы макросов, как только они готовы к использованию.
Разделение проекта
Одним из важных и всё более актуальных вопросов в экосистеме аналитической инженерии является то, как и когда разделять кодовую базу на несколько dbt‑проектов. В настоящее время наша рекомендация для большинства команд, особенно для тех, кто только начинает, достаточно проста: в большинстве случаев мы советуем делать это с помощью Mesh!
Mesh позволяет организациям управлять сложностью, связывая несколько dbt‑проектов, вместо того чтобы полагаться на один большой монолитный проект. Такой подход разработан для ускорения разработки при одновременном сохранении управляемости и стандартов (governance).
По мере того, как разделение монолитных dbt проектов на более мелкие, связанные проекты, возможно, в рамках современного моно-репозитория становится проще, сценарии, которые мы в настоящее время не рекомендуем, могут вскоре стать осуществимыми. Так что следите за обновлениями!
- ✅ Бизнес‑группы или подразделения. Концептуальное разделение внутри проекта — основная причина для его декомпозиции. Это позволяет бизнес‑доменам владеть собственными дата‑продуктами и при этом продолжать совместную работу с использованием Mesh. Подробнее о Mesh см. в разделе FAQ по Mesh.
- ✅ Управление данными (data governance). Структурные и организационные требования — такие как управление данными и безопасность — относятся к немногим действительно оправданным причинам для разделения проекта. Например, если вы работаете в медицинской компании, где лишь небольшая команда имеет доступ к сырым данным с PII, может потребоваться вынести staging‑модели в отдельные проекты, чтобы сохранить эти политики. В таком случае staging‑проект импортируется в проект, который строится поверх этих моделей, в виде приватного пакета.
- ✅ Размер проекта. В какой‑то момент проект может вырасти до такого масштаба, что количество моделей начнёт негативно влиять на удобство разработки. Если у вас тысячи моделей, имеет смысл найти способ разделить проект.
- ❌ Сценарии ML vs отчётность. Аналогично предыдущему пункту, распространённая идея — разделять проект по сценариям использования, в частности между классической BI‑аналитикой и ML‑функциональностью. Мы рекомендуем пока этого избегать. Как и выше, одна из базовых целей внедрения dbt — создание единого источника истины в организации. Функциональность, которую вы предоставляете командам data science, должна строиться на тех же marts и метриках, что и отчёты для руководящих дашбордов.
Заключительные соображения
В целом, последовательность важнее, чем любые из этих конкретных соглашений. По мере роста вашего проекта и углубления вашего опыта с dbt, вы, несомненно, найдете аспекты вышеуказанной структуры, которые захотите изменить. Хотя мы рекомендуем этот подход для большинства проектов, каждая организация уникальна! Единственный догматический совет, который мы здесь дадим, заключается в том, что когда вы находите аспекты вышеуказанной структуры, которые хотите изменить, тщательно обдумайте свои причины и задокументируйте для вашей команды как и почему вы отклоняетесь от этих соглашений. В этой связи мы настоятельно рекомендуем вам форкнуть это руководство и добавить его в README вашего проекта, вики или документацию, чтобы вы могли быстро создать и настроить эти артефакты.
Наконец, мы подчеркиваем, что это руководство является живым документом! Оно, безусловно, будет изменяться и расти по мере эволюции dbt и dbt Labs. Мы приглашаем вас присоединиться — обсуждать, комментировать и вносить предложения по изменениям или новым элементам для освещения.