<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Yuriy Gavrilov: posts tagged ETL</title>
<link>https://gavrilov.info/tags/etl/</link>
<description>Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov</description>
<author></author>
<language>en</language>
<generator>Aegea 11.4 (v4171e)</generator>

<itunes:owner>
<itunes:name></itunes:name>
<itunes:email>yvgavrilov@gmail.com</itunes:email>
</itunes:owner>
<itunes:subtitle>Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov</itunes:subtitle>
<itunes:image href="https://gavrilov.info/pictures/userpic/userpic-square@2x.jpg?1643451008" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Современный семантический слой на dbt + MetricFlow + DuckDB: макросы вместо пакетов</title>
<guid isPermaLink="false">350</guid>
<link>https://gavrilov.info/all/sovremenny-semanticheskiy-sloy-na-dbt-metricflow-duckdb-makrosy/</link>
<pubDate>Wed, 09 Sep 2026 22:52:12 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/sovremenny-semanticheskiy-sloy-na-dbt-metricflow-duckdb-makrosy/</comments>
<description>
&lt;p&gt;В этой статье мы построим полностью рабочий семантический слой для аналитики на данных Superstore.csv (от Tableau Desktop, можно скачать его где-то), используя &lt;b&gt;dbt&lt;/b&gt;, &lt;b&gt;MetricFlow&lt;/b&gt; и &lt;b&gt;DuckDB&lt;/b&gt;. Вместо устаревшего пакета `dbt_metrics` (который несовместим с dbt 1.12+), мы применим &lt;b&gt;современный подход&lt;/b&gt; — вынесем логику метрик в &lt;b&gt;макросы dbt&lt;/b&gt;. Это позволяет централизованно управлять расчётами, автоматически обновлять витрины при изменении метрик и использовать семантический слой для ad-hoc-запросов через `mf`. Все шаги проверены на последних версиях инструментов и готовы к использованию в реальных проектах.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/image-245.png" width="2088" height="456" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;1. Зачем нужен семантический слой и почему макросы — это современный подход?&lt;/h3&gt;
&lt;p&gt;Семантический слой решает ключевые проблемы аналитики:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Единое место определения метрик&lt;/b&gt; — бизнес-логика хранится в одном файле.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Автоматическая генерация SQL&lt;/b&gt; — не нужно писать `GROUP BY`, `JOIN` и агрегации вручную для ad-hoc-запросов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Согласованность&lt;/b&gt; — аналитики и BI-инструменты используют одни и те же метрики.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ранее для использования метрик в моделях применялся пакет `dbt_metrics`, но он &lt;b&gt;несовместим с dbt 1.12 и выше&lt;/b&gt; (требует версию &lt;1.6.0). Современный подход — **выносить выражения метрик в макросы dbt**. Это:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Не требует внешних пакетов.&lt;/li&gt;
&lt;li&gt;Работает с любой версией dbt.&lt;/li&gt;
&lt;li&gt;Даёт полный контроль над SQL.&lt;/li&gt;
&lt;li&gt;Легко поддерживается и версионируется.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Мы будем использовать:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;dbt&lt;/b&gt; 1.12.4 — для управления моделями и витринами.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MetricFlow&lt;/b&gt; (встроенный в dbt) — для семантического слоя и ad-hoc-запросов через `mf`.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DuckDB&lt;/b&gt; 1.5.5 — лёгкая БД для разработки.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Макросы dbt&lt;/b&gt; — для переиспользования логики метрик в витринах.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;2. Установка инструментов и создание проекта&lt;/h3&gt;
&lt;p&gt;Используем `uv` — быстрый менеджер пакетов Python.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mkdir dbtflow_duck
cd dbtflow_duck

uv init
uv venv
source .venv/bin/activate

uv pip install dbt-duckdb dbt-metricflow pandas duckdb&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Проверяем версии (на момент написания):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dbt-core: 1.12.4&lt;/li&gt;
&lt;li&gt;duckdb: 1.5.5&lt;/li&gt;
&lt;li&gt;metricflow: 0.212.0&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;3. Загрузка данных Superstore&lt;/h3&gt;
&lt;p&gt;Скачайте `Superstore.csv` (например, с Kaggle) и поместите в корень проекта.&lt;/p&gt;
&lt;p&gt;Создайте `load_data.py`:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;import pandas as pd
import duckdb

df = pd.read_csv('Superstore.csv', sep='\t', encoding='latin1')
df.columns = [col.lower().replace(' ', '_').replace('/', '_').replace('-', '_') for col in df.columns]

for col in ['sales', 'discount', 'profit']:
    if col in df.columns:
        df[col] = df[col].astype(str).str.replace(',', '.').astype(float)

df['order_date'] = pd.to_datetime(df['order_date'], dayfirst=True)
df['ship_date'] = pd.to_datetime(df['ship_date'], dayfirst=True)
df['postal_code'] = df['postal_code'].astype(str)

db_path = 'dbtflow_duck.duckdb'
con = duckdb.connect(db_path)

con.execute(&amp;quot;DROP TABLE IF EXISTS superstore&amp;quot;)
con.execute(&amp;quot;&amp;quot;&amp;quot;
CREATE TABLE superstore (
    row_id INTEGER, order_id VARCHAR, order_date DATE, ship_date DATE,
    ship_mode VARCHAR, customer_id VARCHAR, customer_name VARCHAR, segment VARCHAR,
    country_region VARCHAR, city VARCHAR, state VARCHAR, postal_code VARCHAR,
    region VARCHAR, product_id VARCHAR, category VARCHAR, sub_category VARCHAR,
    product_name VARCHAR, sales DOUBLE, quantity INTEGER, discount DOUBLE, profit DOUBLE
)
&amp;quot;&amp;quot;&amp;quot;)

con.execute(&amp;quot;INSERT INTO superstore SELECT * FROM df&amp;quot;)
print(f&amp;quot;✅ Загружено {len(df)} строк в {db_path}&amp;quot;)
con.close()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Запуск:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;python load_data.py&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h3&gt;4. Инициализация dbt-проекта вручную&lt;/h3&gt;
&lt;p&gt;Создаём папку проекта и файлы конфигурации (без `dbt init`, чтобы избежать проблем):&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mkdir dbt_project
cd dbt_project&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;dbt_project.yml&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;name: 'dbt_project'
version: '1.0.0'
profile: 'dbt_project'

model-paths: [&amp;quot;models&amp;quot;]
analysis-paths: [&amp;quot;analyses&amp;quot;]
test-paths: [&amp;quot;tests&amp;quot;]
seed-paths: [&amp;quot;seeds&amp;quot;]
macro-paths: [&amp;quot;macros&amp;quot;]
snapshot-paths: [&amp;quot;snapshots&amp;quot;]

clean-targets:
  - &amp;quot;target&amp;quot;
  - &amp;quot;dbt_packages&amp;quot;

models:
  dbt_project:
    +materialized: table&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;profiles.yml&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;dbt_project:
  target: dev
  outputs:
    dev:
      type: duckdb
      path: ../dbtflow_duck.duckdb
      schema: main
      threads: 4&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Создаём структуру папок:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mkdir -p models analyses tests seeds macros snapshots
export DBT_PROFILES_DIR=$(pwd)
dbt debug   # должно быть All checks passed!&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h3&gt;5. Модели данных&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;models/sources.yml&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;version: 2

sources:
  - name: default
    schema: main
    tables:
      - name: superstore&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;models/superstore_clean.sql&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ config(materialized='table') }}

SELECT
    row_id,
    order_id,
    order_date,
    ship_date,
    ship_mode,
    customer_id,
    customer_name,
    segment,
    country_region,
    city,
    state,
    postal_code,
    region,
    product_id,
    category,
    sub_category,
    product_name,
    sales,
    quantity,
    discount,
    profit
FROM {{ source('default', 'superstore') }}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;models/time_spine.sql&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ config(materialized='table') }}

SELECT 
    CAST(generate_series AS DATE) AS date_day
FROM generate_series(DATE '2020-01-01', DATE '2026-12-31', INTERVAL '1' DAY)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;models/metricflow_time_spine.yml&lt;/b&gt; (обязательно для MetricFlow):&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;models:
  - name: time_spine
    description: &amp;quot;A time spine with one row per day for MetricFlow.&amp;quot;
    time_spine:
      standard_granularity_column: date_day
    columns:
      - name: date_day
        granularity: day&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h3&gt;6. Семантическая модель и метрики&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;models/superstore.yml&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;semantic_models:
  - name: superstore
    model: ref('superstore_clean')
    description: &amp;quot;Superstore sales data&amp;quot;
    defaults:
      agg_time_dimension: order_date
    
    entities:
      - name: order_id
        type: primary
        
    dimensions:
      - name: order_date
        type: time
        type_params:
          time_granularity: day
      - name: category
        type: categorical
      - name: region
        type: categorical
    
    measures:
      - name: total_sales
        agg: sum
        expr: sales
      - name: total_profit
        agg: sum
        expr: profit
      - name: total_discount
        agg: average          # Внимание: не &amp;quot;avg&amp;quot;, а &amp;quot;average&amp;quot;!
        expr: discount

metrics:
  - name: total_sales
    label: Total Sales
    type: simple
    type_params:
      measure: total_sales
  - name: total_profit
    label: Total Profit
    type: simple
    type_params:
      measure: total_profit
  - name: avg_discount
    label: Average Discount
    type: simple
    type_params:
      measure: total_discount
  - name: profit_margin
    label: Profit Margin
    type: derived
    type_params:
      expr: total_profit / total_sales
      metrics:
        - total_profit
        - total_sales&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Выполняем сборку и генерацию артефактов:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;dbt run
dbt parse&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h3&gt;7. Ad-hoc-запросы через MetricFlow CLI (`mf`)&lt;/h3&gt;
&lt;p&gt;Проверяем конфигурацию:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mf validate-configs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Список метрик:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mf list metrics&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Вывод:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;• avg_discount: metric_time, order_id__category, order_id__order_date, order_id__region
• profit_margin: metric_time, order_id__category, order_id__order_date, order_id__region
• total_profit: metric_time, order_id__category, order_id__order_date, order_id__region
• total_sales: metric_time, order_id__category, order_id__order_date, order_id__region&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Примеры запросов:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mf query --metrics total_sales --group-by order_id__category
mf query --metrics profit_margin --group-by order_id__region
mf query --metrics avg_discount --group-by order_id__category&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-09-v-22.44.49.png" width="1638" height="630" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;MetricFlow генерирует SQL автоматически — мы не пишем ни строчки кода для этих запросов.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;8. Современный подход: макросы для переиспользования метрик в витринах&lt;/h3&gt;
&lt;p&gt;Вместо устаревшего пакета `dbt_metrics` мы создадим &lt;b&gt;макросы&lt;/b&gt;, которые возвращают SQL-выражение для каждой метрики. Это позволяет:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Централизованно управлять логикой расчёта.&lt;/li&gt;
&lt;li&gt;Использовать одну и ту же логику во всех витринах.&lt;/li&gt;
&lt;li&gt;Легко изменять метрику в одном месте.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;macros/get_metric_expr.sql&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{% macro get_total_sales_expr() %}
    SUM(sales)
{% endmacro %}

{% macro get_total_profit_expr() %}
    SUM(profit)
{% endmacro %}

{% macro get_avg_discount_expr() %}
    AVG(discount)
{% endmacro %}

{% macro get_profit_margin_expr() %}
    {{ get_total_profit_expr() }} / NULLIF({{ get_total_sales_expr() }}, 0)
{% endmacro %}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Теперь мы можем строить витрины, используя эти макросы.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;models/sales_by_category.sql&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ config(materialized='table') }}

SELECT
    category,
    {{ get_total_sales_expr() }} AS total_sales
FROM {{ ref('superstore_clean') }}
GROUP BY category&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;models/profit_by_region.sql&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ config(materialized='table') }}

SELECT
    region,
    {{ get_total_profit_expr() }} AS total_profit,
    {{ get_profit_margin_expr() }} AS profit_margin
FROM {{ ref('superstore_clean') }}
GROUP BY region&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;models/avg_discount_by_category.sql&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ config(materialized='table') }}

SELECT
    category,
    {{ get_avg_discount_expr() }} AS avg_discount
FROM {{ ref('superstore_clean') }}
GROUP BY category&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;После добавления новых моделей выполняем `dbt run` — все витрины создаются с актуальной логикой метрик.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;9. Преимущества подхода с макросами&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Совместимость&lt;/b&gt; — работает с любой версией dbt, без внешних пакетов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Гибкость&lt;/b&gt; — можно легко добавлять фильтры, условия, использовать оконные функции.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Прозрачность&lt;/b&gt; — SQL-код виден и контролируется, его легко отлаживать.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Единый источник истины&lt;/b&gt; — метрики определены как в YAML (для `mf`), так и в макросах (для витрин).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Автоматизация&lt;/b&gt; — изменения в макросах автоматически обновляют все витрины при следующем `dbt run`.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;10. Расширенный пример: добавление фильтра в метрику&lt;/h3&gt;
&lt;p&gt;Предположим, нам нужна выручка только для категории “Technology”. Мы можем создать отдельный макрос:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{% macro get_tech_sales_expr() %}
    SUM(CASE WHEN category = 'Technology' THEN sales ELSE 0 END)
{% endmacro %}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;И использовать его в витрине:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ config(materialized='table') }}

SELECT
    region,
    {{ get_tech_sales_expr() }} AS tech_sales
FROM {{ ref('superstore_clean') }}
GROUP BY region&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Это демонстрирует, насколько легко расширять систему без изменения основной семантической модели.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;11. Автоматизация пайплайнов&lt;/h3&gt;
&lt;p&gt;Настройте регулярный запуск `dbt run` в CI/CD или Airflow. При каждом запуске:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Обновляются сырые данные (если они загружаются заново).&lt;/li&gt;
&lt;li&gt;Пересчитываются модели `superstore_clean` и `time_spine`.&lt;/li&gt;
&lt;li&gt;Пересчитываются все витрины с актуальной логикой метрик из макросов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Таким образом, ваши отчёты всегда актуальны, а бизнес-логика централизована.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;12. Заключение&lt;/h3&gt;
&lt;p&gt;Мы построили современный семантический слой на стеке dbt + MetricFlow + DuckDB, используя макросы для переиспользования логики метрик в витринах. Этот подход:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Не требует устаревших пакетов.&lt;/li&gt;
&lt;li&gt;Совместим с последними версиями dbt.&lt;/li&gt;
&lt;li&gt;Даёт полный контроль над SQL.&lt;/li&gt;
&lt;li&gt;Легко масштабируется и поддерживается.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Все команды проверены и работают на практике. Вы можете адаптировать этот проект под свои данные и метрики, получая все преимущества семантического слоя без лишних зависимостей.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Полезные ссылки:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.getdbt.com/docs/use-dbt-semantic-layer/dbt-sl"&gt;dbt Semantic Layer docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://duckdb.org/docs/guides/dbt"&gt;DuckDB + dbt &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.astral.sh/uv/"&gt;uv package manager &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
</description>
</item>

<item>
<title>dbt открывает исходный код MetricFlow: Управляемые метрики для AI и аналитики</title>
<guid isPermaLink="false">292</guid>
<link>https://gavrilov.info/all/dbt-otkryvaet-ishodny-kod-metricflow-upravlyaemye-metriki-dlya-a/</link>
<pubDate>Sat, 01 Nov 2025 01:03:55 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/dbt-otkryvaet-ishodny-kod-metricflow-upravlyaemye-metriki-dlya-a/</comments>
<description>
&lt;p&gt;Компания dbt Labs объявила о важном изменении в своей стратегии: `MetricFlow`, ключевая технология, лежащая в основе `dbt Semantic Layer`, становится полностью открытой. Проект переводится под лицензию Apache 2.0, что позволяет любому использовать, изменять и встраивать его в свои продукты. Это стратегический шаг, направленный на создание единого отраслевого стандарта для определения бизнес-метрик, особенно в свете бурного развития AI-систем.&lt;/p&gt;
&lt;p&gt;Оригинал тут: &lt;a href="https://www.getdbt.com/blog/open-source-metricflow-governed-metrics"&gt;https://www.getdbt.com/blog/open-source-metricflow-governed-metrics&lt;/a&gt;&lt;br /&gt;
А гит тут: &lt;a href="https://github.com/dbt-labs/metricflow"&gt;https://github.com/dbt-labs/metricflow&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Еще кстати есть &lt;a href="https://github.com/memiiso/opendbt"&gt;https://github.com/memiiso/opendbt&lt;/a&gt; ( Make dbt great again! :) Может они сольются с метриками, интересно.&lt;/p&gt;
&lt;h3&gt;Проблема: почему семантический слой стал критически важен&lt;/h3&gt;
&lt;p&gt;Концепция семантического слоя, который служит промежуточным слоем для определения бизнес-логики (метрик, измерений, связей), не нова. Она уже много лет используется в BI-системах для обеспечения согласованности отчетов. Однако с появлением больших языковых моделей (LLM) и инструментов в стиле “Chat with your data” проблема вышла на новый уровень.&lt;/p&gt;
&lt;p&gt;Когда AI-агент или LLM пытается ответить на вопрос, обращаясь напрямую к базе данных, он вынужден самостоятельно генерировать SQL-запрос. При этом модель “угадывает”, какие таблицы нужно соединить (`JOIN`), как правильно отфильтровать данные, какую использовать гранулярность по времени и какие оконные функции применить.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Проблемы такого подхода:&lt;/b&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Несогласованность:&lt;/b&gt; Две разные модели (или даже одна и та же, но с другим запросом) могут сгенерировать разный SQL для расчета, казалось бы, одной и той же метрики. Это приводит к разным цифрам в отчетах.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ошибки:&lt;/b&gt; LLM может не знать о тонкостях бизнес-логики, например, о том, что при расчете выручки нужно учитывать возвраты или использовать специальный финансовый календарь.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Потеря доверия:&lt;/b&gt; Когда пользователи получают противоречивые или неверные данные, доверие ко всей системе аналитики быстро падает.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Метрики не должны быть вероятностными, зависящими от “догадок” LLM при каждом вызове. &lt;b&gt;Они должны быть детерминированными.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;`MetricFlow` решает именно эту задачу.&lt;/p&gt;
&lt;h3&gt;Что такое MetricFlow и как он работает&lt;/h3&gt;
&lt;p&gt;`MetricFlow` — это движок, который преобразует семантические определения бизнес-понятий в готовый к выполнению и оптимизированный SQL-код. Аналитик один раз определяет метрику “Валовая маржа” на языке `MetricFlow`, и после этого любая система (BI-инструмент, AI-агент, Python-скрипт) может запросить эту метрику по имени, будучи уверенной, что получит корректный и одинаковый результат.&lt;/p&gt;
&lt;h3&gt;Ключевые изменения и их значение&lt;/h3&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Лицензия Apache 2.0:&lt;/b&gt; Это одно из главных нововведений. Apache 2.0 — это разрешительная лицензия, которая позволяет другим компаниям свободно встраивать `MetricFlow` в свои коммерческие и открытые продукты. Это снимает барьеры для принятия технологии и способствует ее распространению как стандарта.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Сотрудничество с Open Semantic Interchange (OSI):&lt;/b&gt; dbt Labs будет развивать `MetricFlow` совместно с такими партнерами, как Snowflake и Salesforce, в рамках инициативы OSI. Цель — создать единый стандарт для семантической совместимости между разными платформами, чтобы метрики, определенные один раз, одинаково работали во всех инструментах.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Как MetricFlow обеспечивает надежность AI&lt;/h3&gt;
&lt;p&gt;`MetricFlow` предоставляет открытый стандарт для метаданных и расширяемый движок, который превращает намерение (“покажи валовую маржу”) в SQL-запрос для хранилища данных.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Пример работы:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Предположим, пользователь задает AI-агенту вопрос:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Покажи валовую маржу (%) по месяцам за прошлый квартал для Северной Америки (за вычетом скидок и возвратов, по финансовому календарю).”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Без семантического слоя LLM пришлось бы конструировать сложный запрос с нуля. С `MetricFlow` процесс выглядит так:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Агент распознает намерение и запрашивает у `MetricFlow` метрику `gross_margin_pct` с нужными измерениями (`region`, `fiscal_month`) и фильтрами.&lt;/li&gt;
&lt;li&gt;`MetricFlow`, на основе заранее созданных определений, строит план запроса:
&lt;ul&gt;
  &lt;li&gt;Находит нужные таблицы: `orders`, `discounts`, `returns`, `cogs` (себестоимость).&lt;/li&gt;
  &lt;li&gt;Применяет правильные `JOIN` между ними.&lt;/li&gt;
  &lt;li&gt;Применяет фильтр по региону (`North America`).&lt;/li&gt;
  &lt;li&gt;Группирует данные по месяцам финансового, а не календарного, года.&lt;/li&gt;
  &lt;li&gt;Рассчитывает числитель (выручка) и знаменатель (себестоимость) с учетом того, что популяция данных для них должна быть одинаковой.&lt;/li&gt;
  &lt;li&gt;Вычисляет итоговое соотношение.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;`MetricFlow` компилирует этот план в оптимизированный SQL-запрос, специфичный для диалекта конкретного хранилища (Snowflake, BigQuery, Databricks и т.д.).&lt;/li&gt;
&lt;li&gt;Запрос выполняется в хранилище, и результат возвращается пользователю.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;При этом весь сгенерированный SQL доступен для проверки, что обеспечивает &lt;b&gt;прозрачность и объяснимость&lt;/b&gt; вычислений.&lt;/p&gt;
&lt;h3&gt;Основные возможности движка:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Единое определение, выполнение где угодно:&lt;/b&gt; Метрики и измерения определяются один раз, а `MetricFlow` компилирует их в SQL для разных диалектов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Оптимизация производительности:&lt;/b&gt; Движок строит эффективные запросы, чтобы избежать лишних сканирований и снизить нагрузку на хранилище данных.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Поддержка сложных вычислений:&lt;/b&gt; `MetricFlow` из коробки обрабатывает сложные соединения, оконные функции, расчеты по когортам и полуаддитивные метрики (например, остатки на счетах, которые нельзя просто суммировать по времени).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;`MetricFlow` vs. `dbt Semantic Layer`&lt;/h3&gt;
&lt;p&gt;Важно понимать различие между двумя компонентами:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;`MetricFlow`&lt;/b&gt; — это движок с открытым исходным кодом для &lt;b&gt;определения и вычисления&lt;/b&gt; метрик. Это “сердце” системы, которое выполняет всю сложную работу по генерации SQL.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`dbt Semantic Layer`&lt;/b&gt; — это коммерческий продукт dbt Labs, построенный *поверх* `MetricFlow`. Он добавляет функциональность корпоративного уровня:
&lt;ul&gt;
  &lt;li&gt;Управление доступом (`RBAC`).&lt;/li&gt;
  &lt;li&gt;Версионирование определений метрик.&lt;/li&gt;
  &lt;li&gt;Аудит и отслеживание происхождения данных (`lineage`).&lt;/li&gt;
  &lt;li&gt;Надежные API и коннекторы для интеграции с BI- и AI-инструментами.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Таким образом, `MetricFlow` становится общедоступным строительным блоком, а `dbt Semantic Layer` — готовым решением для его безопасного и управляемого внедрения в компаниях.&lt;/p&gt;
&lt;h3&gt;Итог&lt;/h3&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;dbt Labs сделала `MetricFlow` (движок для расчета метрик) полностью открытым под лицензией Apache 2.0.&lt;/b&gt; Это позволяет всем желающим использовать его без ограничений.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Главная цель — создать открытый стандарт для определения бизнес-метрик.&lt;/b&gt; Это особенно актуально для AI-систем, которые часто ошибаются при самостоятельной генерации SQL.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`MetricFlow` позволяет AI и BI-инструментам запрашивать данные по имени метрики (например, `revenue`), получая детерминированный и корректный SQL-запрос.&lt;/b&gt; Это повышает надежность и согласованность данных.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Этот шаг способствует совместимости инструментов (`interoperability`) и снижает зависимость от конкретного вендора (`vendor lock-in`).&lt;/b&gt; Метрики, определенные один раз, будут работать одинаково в разных системах.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Коммерческий продукт `dbt Semantic Layer` продолжит развиваться&lt;/b&gt; как решение для управления жизненным циклом метрик в корпоративной среде (безопасность, контроль версий, аудит).&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>Новая эра трансформации данных: dbt против Bruin и aaC</title>
<guid isPermaLink="false">272</guid>
<link>https://gavrilov.info/all/novaya-era-transformacii-dannyh-dbt-protiv-bruin-i-aac/</link>
<pubDate>Sat, 23 Aug 2025 16:04:02 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/novaya-era-transformacii-dannyh-dbt-protiv-bruin-i-aac/</comments>
<description>
&lt;p&gt;В мире данных произошла тихая, но фундаментальная революция. На смену традиционному подходу &lt;b&gt;ETL (Extract, Transform, Load)&lt;/b&gt;, где данные преобразовывались до загрузки в хранилище, пришла новая парадигма — &lt;b&gt;ELT (Extract, Load, Transform)&lt;/b&gt;. Благодаря мощности современных облачных хранилищ (таких как Snowflake, BigQuery, Databricks, Starburst\Trino) стало выгоднее сначала загружать сырые данные, а уже затем трансформировать их непосредственно в хранилище.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/demo.gif" width="1200" height="900" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Этот сдвиг породил потребность в инструментах, которые специализируются на последнем шаге — трансформации (T). Именно в этой нише dbt (data build tool) стал безоговорочным лидером, но на его поле появляются и новые сильные игроки, такие как Bruin. Давайте разберемся, что это за инструменты, какой подход они олицетворяют и в чем их ключевые различия.&lt;/p&gt;
&lt;h4&gt;Подход «Аналитика как код»&lt;/h4&gt;
&lt;p&gt;И dbt, и Bruin являются яркими представителями движения &lt;b&gt;“Analytics as Code”&lt;/b&gt; (аналитика как код). Это не просто инструменты, а целая философия, которая переносит лучшие практики разработки программного обеспечения в мир аналитики данных.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Основные принципы и идеи:&lt;/b&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Версионирование:&lt;/b&gt; Все трансформации данных описываются в виде кода (в основном SQL), который хранится в системе контроля версий, такой как Git. Это позволяет отслеживать изменения, совместно работать и откатываться к предыдущим версиям.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Модульность и переиспользование (DRY – Don’t Repeat Yourself):&lt;/b&gt; Сложные трансформации разбиваются на небольшие, логически завершенные модели, которые могут ссылаться друг на друга. Это делает код чище, понятнее и позволяет повторно использовать уже написанную логику.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Тестирование:&lt;/b&gt; Код трансформаций должен быть протестирован. Инструменты позволяют автоматически проверять качество данных после преобразований: на уникальность ключей, отсутствие `NULL` значений, соответствие заданным условиям и т.д.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Документация и прозрачность:&lt;/b&gt; Процесс трансформации становится самодокументируемым. Инструменты могут автоматически генерировать документацию и строить графы зависимостей моделей (data lineage), показывая, как данные текут и преобразуются от источника к конечному виду. &lt;a href="https://www.element61.be/en/resource/when-use-dbt-or-delta-live-tables"&gt;element61.be&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CI/CD (Continuous Integration / Continuous Deployment):&lt;/b&gt; Изменения в коде трансформаций могут автоматически тестироваться и разворачиваться в продуктивную среду, что значительно ускоряет циклы разработки.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;Решаемые проблемы:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;“Черные ящики” ETL:&lt;/b&gt; Заменяют сложные, трудноподдерживаемые и непрозрачные ETL-процессы на понятный и документированный код.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Рассинхронизация команд:&lt;/b&gt; Стирают границы между инженерами данных и аналитиками, позволяя аналитикам, владеющим SQL, самостоятельно создавать надежные модели данных.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Низкое качество данных:&lt;/b&gt; Встроенные механизмы тестирования помогают обеспечить надежность и согласованность данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;---&lt;/p&gt;
&lt;h4&gt;dbt (data build tool): Золотой стандарт трансформации&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;dbt&lt;/b&gt; — это инструмент с открытым исходным кодом, который позволяет аналитикам и инженерам трансформировать данные в их хранилищах с помощью простых SQL-запросов. Важно понимать, что dbt &lt;b&gt;не извлекает и не загружает данные&lt;/b&gt;. Он специализируется исключительно на шаге &lt;b&gt;“T”&lt;/b&gt; в ELT  &lt;a href="https://vutr.substack.com/p/why-is-dbt-so-popular"&gt;vutr.substack.com&lt;/a&gt;. &lt;a href="https://github.com/dbt-labs/dbt-core"&gt;dbt git&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Он работает как компилятор и исполнитель: вы пишете модели данных в `.sql` файлах, используя шаблонизатор Jinja для добавления логики (циклы, условия, макросы). Затем dbt компилирует этот код в чистый SQL и выполняет его в вашем хранилище данных &lt;a href="https://www.element61.be/en/resource/when-use-dbt-or-delta-live-tables"&gt;element61.be&lt;/a&gt;.&lt;/p&gt;
&lt;h5&gt;Плюсы dbt&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Огромное сообщество и экосистема:&lt;/b&gt; dbt стал де-факто стандартом индустрии. Существует огромное количество статей, курсов, готовых пакетов (библиотек) и экспертов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Фокус на SQL:&lt;/b&gt; Низкий порог входа для аналитиков, которые уже знают SQL. Это демократизирует процесс трансформации данных.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Мощное тестирование и документирование:&lt;/b&gt; Встроенные команды для тестирования данных и автоматической генерации проектной документации с графом зависимостей.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Зрелость и надежность:&lt;/b&gt; Инструмент проверен временем и используется тысячами компаний по всему миру.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Гибкость:&lt;/b&gt; Благодаря шаблонизатору Jinja можно создавать очень сложные и переиспользуемые макросы, адаптируя dbt под любые нужды.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Минусы dbt&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Только трансформация:&lt;/b&gt; dbt не занимается извлечением (E) и загрузкой (L). Для этого вам понадобятся отдельные инструменты (например, Fivetran, Airbyte), что усложняет стек технологий.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Кривая обучения:&lt;/b&gt; Хотя основы просты, освоение продвинутых возможностей Jinja, макросов и структуры проекта требует времени.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Зависимость от Python-моделей:&lt;/b&gt; Хотя недавно появилась поддержка моделей на Python, она все еще не так нативна и проста, как основной SQL-подход, и требует дополнительных настроек.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;---&lt;/p&gt;
&lt;h4&gt;Bruin Data: Универсальный боец&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Bruin&lt;/b&gt; — это более новый игрок на рынке, который позиционирует себя как инструмент для создания “end-to-end” пайплайнов данных. В отличие от dbt, он не ограничивается только трансформацией, а стремится охватить больше этапов работы с данными, включая их загрузку (ingestion) &lt;a href="https://github.com/bruin-data/bruin"&gt;https://github.com/bruin-data/bruin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bruin разделяет ту же философию “Analytics as Code”, но предлагает более интегрированный опыт, где SQL и Python являются равноправными гражданами.&lt;/p&gt;
&lt;h5&gt;Плюсы Bruin&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Универсальность:&lt;/b&gt; Один инструмент для определения всего пайплайна: от загрузки из источников до финальных витрин данных. Это может упростить стек технологий.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Нативная поддержка SQL и Python:&lt;/b&gt; Позволяет легко комбинировать задачи на разных языках в одном пайплайне без дополнительных настроек. Это идеально для задач, где чистый SQL громоздок (например, работа с API, машинное обучение).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Простота конфигурации:&lt;/b&gt; Зачастую требует меньше шаблонного кода (boilerplate) для определения ассетов и пайплайнов по сравнению с dbt.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Встроенное качество данных:&lt;/b&gt; Как и dbt, делает акцент на проверках качества на каждом шаге.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Минусы Bruin&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt; Пока маленькое сообщество:&lt;/b&gt; Как у нового инструмента, у Bruin гораздо меньше пользователей, готовых решений и обсуждений на форумах по сравнению с dbt. Найти помощь или готовый пакет для решения специфической задачи сложнее.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Незрелость:&lt;/b&gt; Инструмент моложе, а значит, наверное, потенциально менее стабилен и может иметь меньше интеграций по сравнению с проверенным dbt. Пока нет облачных функция за деньги. Я так думал, но все же есть &lt;a href="https://getbruin.com."&gt;https://getbruin.com.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;“Мастер на все руки — эксперт ни в чем?”:&lt;/b&gt; Стремление охватить все этапы (E, L, T) может означать, что в каждом отдельном компоненте Bruin может уступать лучшим в своем классе специализированным инструментам (например, Fivetran в загрузке, dbt в трансформации), но это конечно субъективно.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Сводное сравнение&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Характеристика&lt;/td&gt;
&lt;td style="text-align: center"&gt;dbt (data build tool)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Bruin Data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Основная задача&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Трансформация (T в ELT)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Весь пайплайн (E, L, T)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Ключевые языки&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;SQL с шаблонизатором Jinja&lt;/td&gt;
&lt;td style="text-align: center"&gt;SQL и Python как равноправные&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Экосистема&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Огромная, стандарт индустрии&lt;/td&gt;
&lt;td style="text-align: center"&gt;Маленькая, развивающаяся&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Зрелость&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Высокая, проверен временем&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая/Средняя&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Стек инструментов&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Требует отдельных E/L инструментов&lt;/td&gt;
&lt;td style="text-align: center"&gt;Стремится быть самодостаточным&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Итого&lt;/h4&gt;
&lt;p&gt;Выбор между dbt и Bruin — это выбор между двумя стратегиями построения современного стека данных.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Выбирайте dbt, если:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Вы строите гибкий стек из лучших в своем классе инструментов (“best-of-breed”): один для загрузки, другой для хранения, третий для трансформации.&lt;/li&gt;
&lt;li&gt;Ваша команда в основном состоит из аналитиков, сильных в SQL.&lt;/li&gt;
&lt;li&gt;Для вас критически важны поддержка сообщества, стабильность и наличие готовых решений.&lt;/li&gt;
&lt;li&gt;Вы работаете в большой организации, где принятие отраслевых стандартов является преимуществом.&lt;/li&gt;
&lt;li&gt;Вы готовы переехать к ним в платное облако, когда нибудь. Большая часть функционала доступна там.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Выбирайте Bruin, если:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Вы предпочитаете единый, интегрированный инструмент для управления всеми пайплайнами, чтобы упростить архитектуру&lt;/li&gt;
&lt;li&gt;Вы любите open source и End-to-end дата framework: фор data ingestion + transformations + кволити. :)&lt;/li&gt;
&lt;li&gt;Ваши пайплайны требуют тесной связки SQL и Python для трансформаций (например, обогащение данных через вызовы API или модели ML).&lt;/li&gt;
&lt;li&gt;Вы начинаете новый проект или работаете в небольшой команде и цените скорость настройки и меньшее количество движущихся частей.&lt;/li&gt;
&lt;li&gt;Вы Go’шник :) –  Bruin написан на Go почти на 100%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;И dbt, и Bruin — мощные инструменты, воплощающие современные подходы к инженерии данных. dbt предлагает проверенный, сфокусированный и невероятно мощный движок для трансформаций, ставший стандартом. Bruin же предлагает более универсальный и интегрированный подход, который может быть привлекателен для команд, стремящихся к простоте и нативной поддержке Python.&lt;/p&gt;
&lt;h4&gt;А что такое “Аналитика как код” (Analytics as Code, AaC)?&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;Аналитика как код&lt;/b&gt; — это подход к управлению аналитическими процессами, при котором все компоненты аналитики — от моделей данных и метрик до отчетов и правил доступа — определяются в виде кода в человекочитаемых файлах. Эти файлы затем управляются так же, как исходный код любого другого программного обеспечения: с помощью систем контроля версий, автоматизированного тестирования и развертывания &lt;a href="https://medium.com/gooddata-developers/analytics-as-code-managing-analytics-solutions-like-any-other-software-504372ba6a61"&gt;medium.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Самая близкая и известная аналогия — это &lt;b&gt;Infrastructure as Code (IaC)&lt;/b&gt;. Как IaC (например, с помощью Terraform) позволил инженерам описывать серверы, сети и базы данных в коде вместо ручной настройки через веб-интерфейсы, так и AaC позволяет описывать в коде всё, что связано с данными &lt;a href="https://medium.com/@terezacihelkova/analytics-as-code-what-is-it-and-how-does-it-help-you-93e9a3c179ee"&gt;medium.com&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Идея проста и убедительна: “настройте свои системы один раз, выразите это в виде кода, а затем поместите в систему контроля версий” &lt;a href="https://www.holistics.io/blog/analytics-as-code/"&gt;holistics.io&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Проблема: Как было раньше?&lt;/h4&gt;
&lt;p&gt;Чтобы понять ценность AaC, нужно посмотреть на проблемы, которые он решает. В традиционном подходе аналитика часто была разрозненной и хрупкой:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Логика в “черных ящиках”:&lt;/b&gt; Сложные преобразования данных были скрыты внутри GUI-интерфейсов старых ETL-инструментов или непосредственно в настройках BI-платформы (например, Tableau, Power BI). Никто, кроме автора, не мог легко понять, как рассчитывается та или иная метрика.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Разрозненные SQL-скрипты:&lt;/b&gt; Аналитики хранили важные SQL-запросы на своих локальных машинах, в общих папках или на wiki-страницах. Не было единой версии правды, код дублировался и быстро устаревал.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Отсутствие контроля версий:&lt;/b&gt; Невозможно было отследить, кто, когда и почему изменил логику расчета ключевого показателя. Откат к предыдущей работающей версии был настоящей головной болью.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;“Ручное” тестирование:&lt;/b&gt; Проверка качества данных после изменений была ручным, подверженным ошибкам процессом. Часто о проблемах узнавали уже от бизнес-пользователей, которые видели неверные цифры в отчетах.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Рассинхронизация:&lt;/b&gt; Инженеры данных готовили сырые таблицы, а аналитики строили свою логику поверх них. Любые изменения с одной стороны могли сломать всю цепочку, не будучи замеченными вовремя.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Этот хаос приводил к главному — &lt;b&gt;недоверию к данным&lt;/b&gt;. Никто не мог быть уверен, что цифры в дашборде верны.&lt;/p&gt;
&lt;h4&gt;Ключевые принципы “Аналитики как код”&lt;/h4&gt;
&lt;p&gt;AaC решает эти проблемы, внедряя практики из мира разработки ПО.&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Декларативное определение:&lt;/b&gt; Все аналитические артефакты описываются в файлах.
&lt;ul&gt;
  &lt;li&gt;Модели данных:** `SELECT * FROM ...` в `.sql` файлах.&lt;/li&gt;
  &lt;li&gt;Тесты:** `not_null`, `unique` в `.yml` файлах.&lt;/li&gt;
  &lt;li&gt;Документация:** Описания таблиц и полей в `.yml` файлах.&lt;/li&gt;
  &lt;li&gt;Метрики и дашборды:** Определения в `.yml` или специализированных файлах &lt;a href="https://medium.com/gooddata-developers/analytics-as-code-managing-analytics-solutions-like-any-other-software-504372ba6a61"&gt;medium.com&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;b&gt;Контроль версий (Git):&lt;/b&gt; Весь код хранится в репозитории (например, на GitHub или GitLab).
&lt;ul&gt;
  &lt;li&gt;Прозрачность:** Каждое изменение — это `commit` с понятным описанием.&lt;/li&gt;
  &lt;li&gt;Совместная работа:** Аналитики работают в отдельных ветках, а изменения вносятся через `Pull Request` (или `Merge Request`), что позволяет проводить ревью кода (code review).&lt;/li&gt;
  &lt;li&gt;Восстанавливаемость:** Если что-то пошло не так, можно легко откатиться к предыдущей версии.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;b&gt;Автоматизированное тестирование:&lt;/b&gt; Тесты являются неотъемлемой частью кода. Они запускаются автоматически при каждом изменении, чтобы гарантировать, что данные по-прежнему соответствуют ожиданиям (например, `user_id` всегда уникален и не равен `NULL`).&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="4"&gt;
&lt;li&gt;&lt;b&gt;CI/CD (Непрерывная интеграция и развертывание):&lt;/b&gt; Процессы полностью автоматизированы.
&lt;ul&gt;
  &lt;li&gt;Когда аналитик вносит изменения в `Pull Request`, автоматически запускаются тесты.&lt;/li&gt;
  &lt;li&gt;После одобрения и слияния ветки изменения автоматически развертываются в продуктивной среде (например, dbt Cloud или Jenkins запускает команду `dbt run`).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;&lt;b&gt;Модульность и переиспользование (DRY – Don’t Repeat Yourself):&lt;/b&gt; Сложные потоки данных разбиваются на небольшие, логичные и переиспользуемые модели. Одна модель может ссылаться на другую, создавая четкий граф зависимостей (lineage), который можно визуализировать.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Преимущества подхода AaC&lt;/h4&gt;
&lt;p&gt;Принятие этой философии дает компании ощутимые выгоды:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Надежность и доверие:&lt;/b&gt; Благодаря автоматическому тестированию и ревью кода значительно повышается качество данных, а вместе с ним и доверие бизнеса к аналитике.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Скорость и гибкость:&lt;/b&gt; Аналитики могут вносить изменения гораздо быстрее. Цикл от идеи до готового отчета сокращается с недель до дней или даже часов.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Масштабируемость:&lt;/b&gt; Кодовая база легко поддерживается и расширяется. Новые члены команды могут быстро разобраться в проекте благодаря документации и прозрачности.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Прозрачность и обнаруживаемость:&lt;/b&gt; Автоматически сгенерированная документация и графы зависимостей позволяют любому сотруднику понять, откуда берутся данные и как они рассчитываются.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Демократизация:&lt;/b&gt; AaC дает возможность аналитикам, владеющим SQL, самостоятельно создавать надежные и протестированные модели данных, не дожидаясь инженеров данных. Это стирает барьеры между командами.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В конечном итоге, “Аналитика как код” — это культурный сдвиг, который превращает аналитику из ремесленного занятия в зрелую инженерную дисциплину, обеспечивая скорость, надежность и масштабируемость, необходимые современному бизнесу.&lt;/p&gt;
</description>
</item>


</channel>
</rss>