Ускорьте работу с документацией: Генерация документации для целых папок сразу
В Lunar большинство наших dbt моделей берут данные из событийно-ориентированной архитектуры. Например, у нас есть следующие модели для папки activity_based_interest
в нашем слое загрузки:
activity_based_interest_activated.sql
activity_based_interest_deactivated.sql
activity_based_interest_updated.sql
downgrade_interest_level_for_user.sql
set_inactive_interest_rate_after_july_1st_in_bec_for_user.sql
set_inactive_interest_rate_from_july_1st_in_bec_for_user.sql
set_interest_levels_from_june_1st_in_bec_for_user.sql
Это приводит к тому, что многие одинаковые колонки (например, account_id
) существуют в разных моделях, в разных слоях. Это означает, что я в итоге:
- Пишу/копирую одну и ту же документацию снова и снова
- На полпути понимаю, что могу улучшить формулировку, чтобы сделать ее более понятной, и возвращаюсь, чтобы обновить файлы
.yml
, которые уже сделал - Понимаю, что сделал синтаксическую ошибку в своем файле
.yml
, поэтому возвращаюсь и исправляю ее - Понимаю, что колонки определены по-разному с использованием разных формулировок в других папках нашего проекта dbt
- Переосмысливаю свой выбор карьеры и молюсь, чтобы большая языковая модель украла мою работу
- Задумываюсь, есть ли лучший способ генерировать документацию, используемую в разных моделях
На самом деле, я нашел лучший способ, используя некоторые команды CLI, пакет dbt Codegen и блоки docs. Я также сделал следующий мем в канале #memes-and-off-topic-chatter в dbt Community Slack, чтобы охарактеризовать этот метод:
Какую проблему решает этот метод?
Если вам нужно документировать одну и ту же колонку несколько раз, этот метод ограничивает ручные ошибки, ускоряет написание и поддержку документации, а также улучшает ее согласованность. Этот метод документации экономит мне 50-80% времени, которое я ранее тратил на документацию, делая процесс документации в dbt более и автоматизированным.
Чему вы научитесь после прочтения этой статьи?
Вы не только научитесь работать с документацией dbt более простым способом, но и станете более знакомыми с пакетом dbt Codegen, блоками docs, регулярными выражениями и командами терми нала.
Обратите внимание, что это решение было протестировано на Mac/VS Code, и поведение регулярных выражений может варьироваться в зависимости от стека.
Предварительные требования
- Опыт написания документации dbt вручную
- Установка dbt, пакета dbt Codegen и VS Code
- Папка в вашем проекте dbt, в которой много недокументированных моделей dbt, где много имен колонок пересекаются между моделями
Исследование
В этой статье мы используем текущую задачу, в которой я сопоставил следующие события, связанные с процентными ставками:
models/core/activity_based_interest
├── events
│ ├── activity_based_interest_activated.sql
│ ├── activity_based_interest_deactivated.sql
│ ├── activity_based_interest_updated.sql
│ ├── downgrade_interest_level_for_user.sql
│ ├── set_inactive_interest_rate_after_july_1st_in_bec_for_user.sql
│ ├── set_inactive_interest_rate_from_july_1st_in_bec_for_user.sql
│ └ ── set_interest_levels_from_june_1st_in_bec_for_user.sql
└── models
└── f_activity_based_interest.sql
Генерация .yml
с помощью пакета Codegen
Пакет dbt Codegen генерирует код dbt и выводит его в командную строку, чтобы вы могли скопировать и вставить его в свой проект dbt. Вместо того чтобы вручную писать содержимое файлов .yml
, вы можете использовать макрос generate_model_yaml
, который запрашивает базу данных для сбора имен таблиц и колонок и выводит это в формате, готовом для копирования и вставки в файл .yml
.
Этот макрос позволяет выполнять команды, такие как:
dbt run-operation generate_model_yaml --args '{"model_names": ["your_model_name",], "upstream_descriptions": true}'
Аргументы, согласно документации Codegen:
model_names
(обязательный): Модель(и), для которых вы хотите сгенерировать YAML.upstream_descriptions
(необязательный,default=False
): Хотите ли вы включить описания для идентичных имен колонок из вышестоящих моделей.
Этот макрос генерирует YAML для списка моделей, который вы затем можете вставить в файл schema.yml
, например:
$ dbt run-operation generate_model_yaml --args '{"model_names": [ "activity_based_interest_activated"] }'
выводит:
13:09:42 Running with dbt=1.3.1
13:09:45 version: 2
models:
- name: activity_based_interest_activated
description: ""
columns:
- name: id
description: ""
- name: user_id
description: ""
- name: start_date
description: ""
- name: end_date
description: ""
- name: tier_threshold_amount
description: ""
- name: tier_interest_percentage
description: ""
- name: event_time
description: ""
- name: event_day
description: ""
Все от version: 2
и далее можно скопировать и вставить в ваш файл .yml
, и вот так вы сэкономили много времени на написание структуры вручную (и неизбежно забыв где-то ", ', или сделав случайную ошибку с отступами...).
Генерация .yml
для нескольких моделей сразу
Для внимательного наблюдателя, model_names
принимает несколько моделей, чем мы можем воспользоваться. Таким образом, нам не нужно запускать этот инструмент один раз на модель. Вместо этого мы можем запустить:
$ dbt run-operation generate_model_yaml --args '{"model_names": [ "activity_based_interest_activated", "activity_based_interest_deactivated", "activity_based_interest_updated", "downgrade_interest_level_for_user", "f_activity_based_interest", "set_inactive_interest_rate_after_july_1st_in_bec_for_user", "set_inactive_interest_rate_from_july_1st_in_bec_for_user", "set_interest_levels_from_june_1st_in_bec_for_user"] }'
Это возвращает один файл .yml
, содержащий документацию для всех моделей, аналогично выше. Вот подмножество результирующего набора:
13:16:21 Running with dbt=1.3.1
13:16:27 version: 2
models:
- name: activity_based_interest_activated
description: ""
columns:
- name: id
description: ""
- name: user_id
description: ""
... (усечено для примера)
- name: set_inactive_interest_rate_after_july_1st_in_bec_for_user
description: ""
columns:
- name: id
description: ""
- name: user_id
description: ""
- name: start_date
description: ""
- name: event_time
description: ""
- name: event_day
description: ""
- name: set_inactive_interest_rate_from_july_1st_in_bec_for_user
description: ""
columns:
- name: id
description: ""
- name: user_id
description: ""
- name: event_time
description: ""
- name: event_day
description: ""
Получение имен моделей программно
Чтобы не писать вручную все имена моделей, мы можем программно собрать имена соответствующих моделей:
$ dbt ls -m models/core/activity_based_interest --output name | xargs -I{} echo -n ' "{}",'
"activity_based_interest_activated", "activity_based_interest_deactivated", "activity_based_interest_updated", "downgrade_interest_level_for_user", "f_activity_based_interest", "set_inactive_interest_rate_after_july_1st_in_bec_for_user", "set_inactive_interest_rate_from_july_1st_in_bec_for_user", "set_interest_levels_from_june_1st_in_bec_for_user",%
dbt ls -m models/core/activity_based_interest
: Эта команда перечисляет все модели dbt в каталоге models/core/activity_based_interest.--output name
: Эта опция фильтрует вывод, чтобы показывать только имя каждой модели, а не контекст + имя модели.| xargs -I{} echo -n ' "{}",'
: Этот пайп отправляет вывод предыдущей команды вxargs
, который выполняет команду echo для каждой строки вывода.-I{}
указывает, что{}
должно быть заменено на имя модели- Команда
echo
затем форматирует имя модели, оборачивая его в двойные кавычки и добавляя запятую и пробел:"model", "name",
- Опция
-n
дляecho
удаляет завершающий символ новой строки
Вывод (⚠️ за исключением последних двух символов ,%
) затем можно скопировать и вставить в следующее:
dbt run-operation generate_model_yaml --args '{"model_names": [ReplaceWithYourOutputFromPreviousCommand]}'
Что, в свою очередь, можно скопировать и вставить в новый файл .yml
. В нашем примере мы записываем его в _activity_based_interest.yml
.
Создание блоков docs для новых колонок
Блоки docs могут быть использованы для написания более DRY и надежной документации. Чтобы использовать блоки docs, обновите структуру папок, чтобы она содержала файл .md
. Ваша структура файлов теперь должна выглядеть следующим образом:
models/core/activity_based_interest
├── _activity_based_interest_docs.md --Новый markdown файл блока docs
├── _activity_based_interest_docs.yml
├── events
│ ├── activity_based_interest_activated.sql
│ ├── activity_based_interest_deactivated.sql
│ ├── activity_based_interest_updated.sql
│ ├── downgrade_interest_level_for_user.sql
│ ├── set_inactive_interest_rate_after_july_1st_in_bec_for_user.sql
│ ├── set_inactive_interest_rate_from_july_1st_in_bec_for_user.sql
│ └── set_interest_levels_from_june_1st_in_bec_for_user.sql
└── models
└── f_activity_based_interest.sql