Установка dbt в Windows и создание первого проекта.
Устанавливал с помощью pip, виртуальное окружение не использовал, так что нужны прописанные в окружении системные переменные. У меня установлена Anaconda, так что системные переменные выглядят так:
1) Запуск cmd от имени администратора pip install dbt-core
Была установлена самая актуальная (на момент написания заметки) версия. Её можно понизить или понизить, указав версию в команде (в следующей команде понизили dbt-core до версии 1.5)
pip install --upgrade dbt-core==1.5
2) После успешной установки устанавливаем коннектор к PostgreSQL.
pip install dbt-postgres
Для установки коннектора к, например, Clickhouse команда была бы pip install dbt-clickhouse
При необходимости установленный коннектор впоследствии можно будет апгрейдить командой
pip install --upgrade dbt-ADAPTER_NAME
3) Проверяем установку командой dbt --version, видим, что всё ок.
4) Запуск настройки проекта командой (рисунок ниже) dbt init kimball_pr (kimball_pr - название учебного проекта), указываем СУБД, которую будем использовать - у нас это единственный вариант (т.к. установлен только 1 коннектор). И указываем реквизиты доступа к PostgreSQL. Это потом можно увидеть в файле profiles.yml, о котором возможно расскажу далее.
5) По рекомендации в последнем сообщении Profile kimball_pr written to C:\Users\Дом\.dbt\profiles.yml using target's profile_template.yml and your supplied values. Run 'dbt debug' to validate the connection запускаем проверку.
6) Запускаем созданный проект.
В итоге смотрим, что в выбранной при настройке проекта БД de101 в схеме kimball появились представление и таблица с соответствующими названиями.
А у нас появилась папка с проектом: c:\IT_Learning\dbt_proj\kimball_pr\ (на самом деле она появилась при выполнении dbt init, но не суть).
DBT успешно установлен и первый проект готов.
Ок, перейдём к следующей задаче. Есть некая таблица заказов, для учебных целей нарежем её на измерения и факты.
Данные брал отсюда https://github.com/Data-Learn/data-engineering/blob/master/DE-101%20Modules/Module02/DE%20-%20101%20Lab%202.1/readme.md - спасибо Диме Аношину и его бесплатному курсу https://datalearn.ru/
Я уже создал в схеме stg таблицу-источник stg.orders для наших таблиц измерений и фактов. Теперь просто можно брать куски кода тут https://github.com/Data-Learn/data-engineering/blob/master/DE-101%20Modules/Module02/DE%20-%20101%20Lab%202.1/from_stg_to_dw.sql и вставлять в файлы моделей.
Создадим пару новых моделей и запустим проект.
Видно, что теперь у нас 4 модели, создано ещё 2 view в указанной схеме.
Возможно, вы спросите: "почему новые объекты создаются как view, а не таблицы?" Ответ прост: если в файле модели не указана в явном виде материализация, то её тип берётся из файла dbt_project.yml
Давайте создадим модель в табличку.
После прогона видим новую таблицу
В реальности вряд ли вы будете запускать весь проект целиком.
Отдельные модели можно запускать, используя ключ models.
dbt run --models geo_dim
Если нужно запустить более 1 модели, названия разделяются запятой. Если в конфиге модели указан таг, можно запустить все модели с этим тагом.
Например, в модели указаны следующие таги
{{ config( materialized='table', tags=['core_layer', 'task1'] ) }}
Тогда все модели с тагом 'core_layer' можно запустить следующей командой:
dbt run --select "tag:core_layer"
При этом желательно в моделях явно прописывать названия моделей, от которых они зависят. Например, если модель model3 должна собираться после моделей model1 и model2, от которых она зависит, эту зависимость в файле model3.sql можно прописать так:
-- depends_on: {{ ref('model1') }}
-- depends_on: {{ ref('model2') }}
Окей, удалю модели из демо, добавлю ещё 2 таблички измерений и везде поставлю материализацию в табличку. Код модели для сбора таблицы фактов ниже.
{{ config(materialized='table') }} select 100+row_number() over() as sales_id ,cust_id ,to_char(order_date,'yyyymmdd')::int as order_date_id ,to_char(ship_date,'yyyymmdd')::int as ship_date_id ,product_dim.prod_id ,shipping_dim.ship_id ,geo_id ,o.order_id ,sales ,profit ,quantity ,discount from stg.orders o inner join {{ ref('shipping_dim') }} on o.ship_mode = shipping_dim.ship_mode inner join {{ ref('geo_dim') }} on o.postal_code = geo_dim.postal_code and geo_dim.country=o.country and geo_dim.city = o.city and o.state = geo_dim.state --City Burlington doesn't have postal code inner join {{ ref('product_dim') }} on o.product_name = product_dim.product_name and o.segment=product_dim.segment and o.subcategory=product_dim.subcategory and o.category=product_dim.category and o.product_id=product_dim.product_id inner join {{ ref('customer_dim') }} on customer_dim.customer_id=o.customer_id and customer_dim.customer_name=o.customer_name
Итого, после успешного выполнения dbt run имеем 5 табличек измерений и 1 табличку фактов. Проект завершён.
P.S. Сделано на Windows 10 и Python 3.9.13
P.P.S. В реальном проекте модели скорее всего будут выглядеть более мудрёно, чем в учебном проекте. Будут и переменные, и макросы, и шаблоны jinja. P.P.P.S.Увидеть, как выглядит финальный селект, сгенерированный моделью, можно в папке на рисунке ниже.