✅ Как это сделать
— Проще всего использовать единую СУБД и разделить ее на набор databases / schemas
— Среда - это лишь совокупность connection details + role + target schema
— В dbt это называется targets и задается в файле profiles.yml
— В зависимости от используемой среды вы хотите модифицировать тот или иной код
✅ Давай примеры
🩷 profiles.yml для dbt с 3-мя средами.
Вместо деталей для подключения используются переменные среды, которые задаются:
— Локально на компьютере пользователя в DEV
— В CI-инструменте (Github Actions) для TEST
— В Orchestration tool (dbtCloud) для PROD
Полностью по ссылке: https://gist.github.com/kzzzr/02d4f1f86d19df9c90210b177a561406
🩷 Limit rows for DEV and TEST with Jinja SQL:
{#- prepare expression to limit rows depending on target.name and flags provided -#}
{%- if target.name in ['prod'] and history_depth_days > 0 -%}
{%- set watermark = 'DATEADD(days, ' ~ -1 * history_depth_days ~ ', CURRENT_TIMESTAMP::DATE)' -%}
{%- set history_depth_expression = timestamp_column ~ ' >= ' ~ watermark -%}
{%- elif target.name not in ['prod'] and limit_data_for_dev == true -%}
{%- set watermark = 'DATEADD(days, ' ~ -1 * var('data_tests_depth_days') ~ ', CURRENT_TIMESTAMP::DATE)' -%}
{%- set history_depth_expression = timestamp_column ~ ' >= ' ~ watermark -%}
{%- else -%}
{%- set history_depth_expression = '1 = 1' -%}
{%- endif -%}
{#- prepare final filter expression -#}
where 1 = 1
and {{ deleted_rows_expression }}
and {{ history_depth_expression }}🩷 Уровень серьезности (Severity) теста: ERROR для PROD, WARN для DEV:
- name: timezone
tests:
- dbt_utils.not_null_proportion:
at_least: 0.95
severity: "{{ 'error' if target.name in ('prod') else 'warn' }}"
🩷 Используемый COMPUTE в зависимости от среды:
{{
config(
materialized='table',
snowflake_warehouse='WH_LARGE' if target.name == 'prod' else target.warehouse
)
}}🩷 Запись артефактов dbt run в метаданные (только для PROD):
on-run-end:
- "{% if target.name == 'prod' %}{{ dbt_artifacts.upload_results(results) }}{% endif %}"
✅ Какие преимущества
— Все пользуются одними и теми же исходными наборами данных (data sources) - исключены расхождения и несогласованность
— Zero effort - не нужно создавать среды как отдельные инстансы, разворачивать ПО, копировать датасеты и следить за актуальностью
— Один проект = один репозиторий с кодом ✔
— Разница поведения и конфигураций для разных сред легко поддерживается с помощью шаблонизации Jinja SQL
— Это экономически выгодно и целесообразно. Используя Snowflake вообще perfect, т.к. у вас decoupled storage & compute, при этом compute unlimited
— Это быстро и безболезненно с точки зрения поставки кода и Time2Market
❤ Расскажите, как эти процессы реализуете вы? В чем недостатки и преимущества подхода?
🌐 @data_apps | Навигация по каналу