Learning Platform
Глоссарий Troubleshooting
Урок 13.04 · 25 мин
Продвинутый
dbt Fusiondbt-autofixmigrationcompatibility

Migration: dbt-autofix и compatibility

В прошлых уроках мы поняли, что Fusion может ускорить ваш local dev и CI fast paths. Но как практически мигрировать существующий проект на 1000+ моделей? Здесь приходит dbt-autofix — инструмент, который dbt Labs разработал для автоматизации миграции на Fusion compatibility.

В этом уроке мы разберём:

  1. Что такое dbt-autofix, зачем он нужен.
  2. Какие конкретные изменения он делает в коде.
  3. Compatibility issues — что Fusion поддерживает, что нет (на 2026 год).
  4. Параллельная эксплуатация Fusion и dbt-core.
  5. dbt-core 1.x продолжает поддерживаться — никакой обязательной миграции.

dis — bytecode introspection + генераторы vs list comprehension

dbt-autofix: что это

dbt-autofix — это утилита от dbt Labs, которая сканирует ваш dbt проект и автоматически вносит изменения, необходимые для совместимости с Fusion engine. Это не «магия» — это deterministic rewriter с набором правил.

# Установка
pip install dbt-autofix

# Сухой прогон — посмотреть, что будет изменено, без применения
dbt-autofix --dry-run .

# Применить изменения
dbt-autofix .

# С опциями
dbt-autofix --target-version=fusion-1.0 --include-tests .

Что autofix умеет на 2026:

dbt-autofix изменения

Типичные изменения после autofix

Рассмотрим примеры реальных автоматических правок.

Пример 1: Macro dispatch

Было (dbt-core compatible):

{% macro my_concat(first, second) %}
  {{ adapter.dispatch('my_concat', 'my_package')(first, second) }}
{% endmacro %}

{% macro default__my_concat(first, second) %}
  CONCAT({{ first }}, {{ second }})
{% endmacro %}

После autofix (Fusion + dbt-core compatible):

{% macro my_concat(first, second) %}
  {{ adapter.dispatch('my_concat', macro_namespace='my_package')(first, second) }}
{% endmacro %}

{% macro default__my_concat(first, second) %}
  CONCAT({{ first }}, {{ second }})
{% endmacro %}

Difference: 'my_package' -> macro_namespace='my_package'. Fusion требует keyword argument для dispatch (более явный). dbt-core backward-compatible с обоими.

Пример 2: Semantic model v1 -> v2

Было (dbt-core 1.x, v1 spec):

# models/_semantic.yml
semantic_models:
  - name: orders
    model: ref('fct_orders')
    entities:
      - name: order_id
        type: primary
    dimensions:
      - name: order_date
        type: time
    measures:
      - name: order_amount
        agg: sum

После autofix (Fusion + dbt-core 1.12, v2 spec):

# models/_models.yml
models:
  - name: fct_orders
    description: "Fact orders"
    semantic_model:
      defaults:
        agg_time_dimension: order_date
      entities:
        - name: order_id
          type: primary
      dimensions:
        - name: order_date
          type: time
          type_params:
            time_granularity: day
      measures:
        - name: order_amount
          agg: sum
          expr: amount

Difference: separate semantic_models: block -> nested semantic_model: под models[]. Это semantic_layer v2 YAML, который мы детально разбираем в модуле 13.

Пример 3: Iceberg config (новое в 2025)

Было (dbt-core менее 1.10):

- name: fct_orders
  config:
    materialized: table
    file_format: iceberg          # outdated key

После autofix (для Iceberg-aware engines):

- name: fct_orders
  config:
    materialized: table
    catalog: iceberg              # new explicit catalog binding
    file_format: parquet          # default within iceberg catalog

Difference: Fusion (и dbt-core 1.10+) использует

explicit catalog binding
для Iceberg vs implicit через file_format.

Пример 4: Snapshot strategy

Было (snapshot inline в SQL):

-- snapshots/customer_snapshot.sql
{% snapshot customer_snapshot %}

{{
    config(
      target_database='snapshots',
      target_schema='customers',
      strategy='timestamp',
      unique_key='customer_id',
      updated_at='updated_at'
    )
}}

SELECT * FROM {{ source('raw', 'customers') }}

{% endsnapshot %}

После autofix (YAML-based snapshots, новое в 1.10):

# snapshots/customer_snapshot.yml
snapshots:
  - name: customer_snapshot
    relation: source('raw', 'customers')
    config:
      database: snapshots
      schema: customers
      strategy: timestamp
      unique_key: customer_id
      updated_at: updated_at

dbt 1.10 ввёл YAML snapshots как preferred способ. Inline .sql snapshots всё ещё работают, но deprecated. Autofix может конвертировать (опционально).


Compatibility matrix (на 2026)

Что работает / не работает в Fusion vs dbt-core:

Feature                          dbt-core 1.12    Fusion 1.0
─────────────────────────────────────────────────────────────
Basic models (SELECT)            [x]                [x]
Incremental materialization      [x]                [x]
Snapshot (timestamp)             [x]                [x]
Snapshot (check)                 [x]                [x]
Microbatch incremental           [x]                [x]
Custom materialization (Jinja)   [x]                [x] (most)
Custom materialization (Python)  [x]                Partial
dbt Python models                [x]                Partial
Macros (basic)                   [x]                [x]
Macros (recursive heavy)         [x]                Partial
Macros (dynamic dispatch)        [x]                [x] (after autofix)
Hooks (pre/post)                 [x]                [x]
Selectors                        [x]                [x]
Sources                          [x]                [x]
Exposures                        [x]                [x]
Documentation (.yml + docs)      [x]                [x]
Tests (data + unit)              [x]                [x]
Semantic Layer v2                [x]                [x]
Model contracts                  [x]                [x]
Cross-project ref (dbt Mesh)     [x]                [x]
Programmatic invocation          [x]                [x] (via subprocess)

Adapter ecosystem:
  Snowflake                      [x] (DBAPI)        [x] (ADBC)
  BigQuery                       [x]                [x] (ADBC)
  Postgres                       [x]                [x] (ADBC)
  Redshift                       [x]                Partial (ADBC dev)
  Databricks                     [x]                Partial
  DuckDB                         [x]                Partial
  ClickHouse                     [x] (community)    Not yet
  Spark/Trino                    [x] (community)    Not yet
WARNING

Partial означает: основные сценарии работают, экзотические могут ломаться. Always test ваш конкретный use case.


Параллельная эксплуатация Fusion и dbt-core

Если решили мигрировать на Fusion для local dev, но оставить dbt-core для production — нужно установить оба. Стандартный pattern:

Setup 1: Через pyenv/asdf isolation

# dbt-core (Python) через pyenv
pyenv install 3.11.5
pyenv local 3.11.5
python -m venv .venv
source .venv/bin/activate
pip install dbt-core dbt-snowflake
# теперь `dbt` в .venv -> dbt-core

# Fusion (binary) через ~/bin
mkdir -p ~/bin
curl -L https://www.getdbt.com/fusion/install.sh | bash -s -- --to ~/bin
# теперь /Users/me/bin/dbt -> Fusion

# Alias для clarity
alias dbt-core='source .venv/bin/activate && dbt'
alias dbt-fusion='~/bin/dbt'

В CI/scripts вызывать через absolute path или alias, не полагаясь на PATH.

Setup 2: Через container isolation

# Dockerfile.dbt-core
FROM python:3.11-slim
RUN pip install dbt-core dbt-snowflake
WORKDIR /project
ENTRYPOINT ["dbt"]

# Dockerfile.fusion
FROM ubuntu:22.04
RUN curl -L https://www.getdbt.com/fusion/install.sh | bash -s -- --to /usr/local/bin
WORKDIR /project
ENTRYPOINT ["dbt"]
# Использование
docker run --rm -v $(pwd):/project dbt-core parse
docker run --rm -v $(pwd):/project dbt-fusion parse

Чисто изолировано. Удобно для CI и shared dev environments.

Setup 3: dbt Cloud CLI

dbt Cloud CLI поддерживает оба engines прозрачно — через flag:

# Use Fusion (default в новых проектах)
dbt --use-engine=fusion parse

# Use dbt-core
dbt --use-engine=core parse

Это самый простой setup, но требует dbt Cloud subscription.


Параллельные target directories

Если бегаете оба engines на одном проекте — артефакты конфликтуют:

project/
├── dbt_project.yml
├── target/                  # ← shared, конфликт
│   ├── manifest.json        # ← кто перезапишет?
│   └── partial_parse.msgpack vs fusion-cache/

Решение — engine-specific target directory:

# dbt_project.yml
target-path: "target/{{ env_var('DBT_ENGINE', 'core') }}"
# Run dbt-core
export DBT_ENGINE=core
dbt parse  # пишет в target/core/

# Run Fusion
export DBT_ENGINE=fusion
dbt parse  # пишет в target/fusion/

Артефакты отдельные, ничего не конфликтует.


dbt-core 1.x продолжает развиваться

Важно зафиксировать: dbt-core не deprecated. Roadmap на 2025-2026:

dbt-core 1.10 (Q3 2025): YAML snapshots, dbt-autofix integration, Iceberg catalog binding
dbt-core 1.11 (Q4 2025): Performance improvements (Cython parser components), dbt-meshify integration
dbt-core 1.12 (April 2026): Semantic Layer v2 YAML, MCP server integration, expanded contracts
dbt-core 1.13 (planning): TBD

dbt Labs official position (Coalesce 2025):

«dbt-core продолжит развиваться как reference implementation. Fusion — speed-up option для тех, кому это нужно. Они coexist.»

Что это означает практически:

  • Не нужно паниковать с миграцией.
  • Учить dbt-core internals (этот курс) — продолжает быть relevant.
  • Production проекты могут оставаться на dbt-core годами без потери features.
  • Community adapters (dbt-clickhouse, dbt-trino, etc.) развиваются на dbt-core base.

Migration checklist (production)

Если решили мигрировать production на Fusion, шаги:

Phase 1: Compatibility audit
  □ Запустить dbt-autofix --dry-run на проекте
  □ Прочитать список изменений
  □ Идентифицировать manual changes (autofix flagged, но не fixed)

Phase 2: Local validation
  □ Применить autofix
  □ Запустить dbt-core parse на всём проекте (должен работать)
  □ Запустить Fusion parse на всём проекте (должен работать)
  □ Сравнить manifest.json (должны быть structurally equal)

Phase 3: Test parity
  □ Запустить dbt-core build на staging (получить run_results.json)
  □ Запустить Fusion build на staging (получить run_results.json)
  □ Сравнить: same number of models, same row counts, same data
  □ Diagnose differences (their root cause)

Phase 4: CI integration
  □ Добавить Fusion CI path (parallel to existing dbt-core CI)
  □ Run на 1-2 недели — собрать confidence
  □ Switch primary CI на Fusion (dbt-core CI остаётся как fallback)

Phase 5: Production switch (carefully)
  □ Schedule rollout window
  □ Switch production engine на Fusion
  □ Monitor 1 week intensively
  □ Have dbt-core fallback ready (rollback в 5 минут)

Phase 6: Long-term
  □ Удалить dbt-core CI после 3 месяцев stable Fusion production
  □ Document migration learnings

Total time для проекта 1000+ моделей: 2-6 недель с senior engineer ownership. Не tries-it-Friday, это full project.


Проверка знанийKnowledge check
Команда хочет мигрировать на Fusion. Один из разработчиков предлагает: 'запустим dbt-autofix, commit изменения, всё работает'. Другой: 'нет, тестируем неделю, затем гипержно мигрируем'. Кто прав?
ОтветAnswer
Оба правы по-разному. Истина — гибридный подход с проверкой на каждом этапе. **Why "просто запустить autofix" недостаточно:** 1. **Autofix покрывает known patterns**, не все edge cases. Если ваш Jinja exotic (heavy meta-programming, custom dispatch chains), autofix может flagить, но не фиксить. Manual changes требуются. 2. **Fusion compatibility !== identical output**. После autofix dbt-core и Fusion могут давать **slightly different** результаты в edge cases: - Different quoting in compiled SQL (semantically equivalent, but different bytes). - Different macro expansion order (resulting same SQL, но не bit-equal). - Different artifact versions (manifest.json compatible, но не bit-equal). 3. **Production-critical paths нужно validate.** Если у вас 1000 моделей, "all green" в dbt parse не означает что все 1000 production runs дадут identical output. **Why "тестируем неделю и hyperjump" тоже недостаточно:** 1. **"Гипержно мигрируем" = big-bang risk.** Если что-то ломается в production — incident, downtime, потенциально потерянные данные. 2. **Месяц тестирования** покажет happy path, но не edge cases. Какой PR merged через 2 месяца внесёт exotic Jinja, который сломает Fusion? Нужны canary-style rollouts, не single big switch. **Правильный подход — phased migration с rollback ready:** **Phase 1 (Week 1): Audit + autofix.** - Запустить 'dbt-autofix --dry-run'. - Review changes carefully. Не accept blindly. - Apply autofix changes commit'ом для review. - Запустить 'dbt parse' на обоих engines — должен работать. **Phase 2 (Weeks 2-3): Local + CI validation.** - Запустить full 'dbt build' на staging на dbt-core. Сохранить run_results.json. - Запустить full 'dbt build' на staging на Fusion. Сравнить. - Differences? Investigate каждое — это либо bug Fusion (reportить), либо expected (document). - Set up CI с Fusion path (parallel к dbt-core CI). Run на каждом PR неделю. **Phase 3 (Week 4): Canary rollout production.** - НЕ переключать production на Fusion сразу. Instead: - Run Fusion на 10% production scope (1 schema, или 1 dag job). - Compare с dbt-core baseline. Если identical — expand scope. - Через неделю — 50%. Через 2 недели — 100%. - Keep dbt-core fallback ready ('git revert' или env variable switch). **Phase 4 (Months 2-3): Validation in production.** - Monitor performance. - Monitor data quality (нет drift). - Monitor error rates. - Collect feedback команды (developer experience improved? regressed?). - Через 3 месяца stable Fusion production — remove dbt-core CI. **Phase 5 (Months 3+): Long-term operations.** - dbt-core knowledge в team — keep some, just in case rollback needed. - Track dbt-core release notes — какие новые features available. - Track Fusion release notes — какие fixes/improvements. **Risk mitigation:** 1. **Rollback plan** на каждой phase. Не "мы сделали migration, теперь stuck on Fusion". Always reversible. 2. **Documentation** — что autofix изменил, какие manual changes, почему. 3. **Communication** с командой — what's changing, what to expect. 4. **Monitoring** — alerts на anomalies в production runs (changed row counts, longer runtime, etc.). **Главный урок:** **migration — это не single decision**, это **multi-month phased process** с validation на каждом этапе. Большие changes в production data infrastructure требуют сadance, не speed. Если кто-то говорит "просто переключим, всё будет работать" — push back. Если кто-то говорит "не торопимся, будем тестировать год" — тоже push back (нет infinite time для каждого решения). Good senior engineering — find balance: phased approach, validate каждую phase, ready to rollback, eventually fully migrate.

Проверка знанийKnowledge check
Senior architect спрашивает: 'если dbt-core продолжит развиваться параллельно с Fusion, что произойдёт через 5 лет? Будут ли они расходиться по features?'
ОтветAnswer
Хороший strategic вопрос. Будущее предсказывать сложно, но можно analyzed several scenarios. **Scenario 1: Convergence (likely).** dbt Labs maintain feature parity между engines. Каждая новая feature появляется в обоих: - semantic_layer v2 — в 1.12 (dbt-core) и Fusion 1.0. - Microbatch incremental — в 1.9 (dbt-core) и Fusion 1.0. - Iceberg catalog binding — в 1.10 (dbt-core) и Fusion 1.0. Это текущая стратегия — Fusion catch-up с dbt-core features. Если это продолжится, через 5 лет оба engines будут feature-equivalent, разница только performance. **Strategic logic:** dbt Labs хочет максимизировать adoption Fusion. Feature parity критична — иначе Fusion users не могут switch back, vice versa. Так что divergence — anti-pattern для dbt Labs business. **Scenario 2: Slow divergence (possible).** Fusion получает features, которые требуют IR (column-level lineage, dialect translation, static optimization). dbt-core эти features не получает (Python implementation не feasible). - Column-level lineage в artifacts. - Cross-warehouse migration tools. - Static SQL optimization suggestions. - AI-powered query suggestions (on top of IR). Это **selective divergence** — Fusion получает premium features, dbt-core остаётся core. Аналогия — Linux kernel vs Red Hat Enterprise Linux distros (kernel free, distro features premium). **Strategic logic:** монетизация Fusion через premium features. Те, кто хочет advanced features, переходят на Fusion. Те, кому достаточно basic dbt — остаются на dbt-core. **Scenario 3: dbt-core deprecation (unlikely but possible).** Через 3-5 лет, если adoption Fusion ≥ 80% community, dbt Labs может deprecate dbt-core активную разработку. Maintenance mode только — security fixes, no new features. Это **slow death** dbt-core. Community adapters (dbt-clickhouse, dbt-trino) которые не имеют Fusion equivalent — стуck. **Strategic logic:** consolidate engineering effort на single engine. Это efficient для dbt Labs, но bad для open source community. **Scenario 4: Fusion BSL converts to OSS (possible, in 3-4 years).** BSL typically converts to Apache 2.0 через 3-4 года. Если Fusion converts: - Fusion становится fully open source. - Community может contribute напрямую. - dbt-core и Fusion convergent codebase возможен (shared internals). **Strategic logic:** часто BSL компании do это после успешного monetization period. **Что значит для меня (senior engineer)?** **Learn**: 1. **Core concepts** — manifest, materializations, dispatch, Jinja contexts. Это **engine-agnostic**. Будет relevant независимо от scenario. 2. **Python dbt-core internals** — это где сейчас deepest knowledge лежит. Каждый бугоор и edge case на dbt-core community доку и Slack обсуждаются. Это valuable. 3. **Rust dbt Fusion internals** — стоит понимать high-level. Не вкладывать deep, пока Fusion ecosystem не созреет. **Career strategy:** - **Конкретный проект**: который engine используется — нужно знать deeply. - **Long-term**: dbt expert = knows both engines, can communicate tradeoffs, can migrate between them. - **Specialization**: если pure Python — focus dbt-core. Если Rust — explore Fusion. - **Не специализироваться на features**, которые могут диversitygnt — focus на core concepts. **Что может случиться неожиданного?** - **Fork**: community может fork dbt-core при serious BSL/divergence issues. Это уже было: dbt-labs fork от Fishtown's original. Open source dynamic — never predictable. - **Acquisition / merger**: dbt Labs merged с Fivetran (Oct 2025). Other moves possible. Strategy могут изменится с new ownership. - **New competitor**: SQLMesh уже существует и растёт. Если SQLMesh capture significant share, dbt Labs strategy may pivot. - **AI revolution**: если LLMs становятся primary way писать SQL, dbt относительная важность может изменится. Multi-вуbsequence. **Главный урок:** future predictions в tech — risk-prone. **Hedge**: invest deeply в **core concepts**, lightly в **engine-specific quirks**, monitor strategy moves regularly (Coalesce conferences, blog posts, hiring patterns). dbt-core remains relevant сейчас. Fusion есть option. Через 5 лет — TBD, но если вы понимаете internals концептуально, переучивание дешёво.

Итого

  1. dbt-autofix автоматизирует большую часть миграции на Fusion. Изменения: macro dispatch syntax, semantic_models v1->v2, Iceberg catalog config, snapshot YAML conversion.
  2. Manual changes требуются для exotic Jinja, custom Python materializations, adapter-specific code.
  3. Compatibility matrix на 2026: основные сценарии работают; advanced/exotic — partial. Always test ваш конкретный use case.
  4. Параллельная эксплуатация — стандарт. Через pyenv/asdf, containers, или dbt Cloud CLI.
  5. dbt-core НЕ deprecated. 1.10, 1.11, 1.12 — active feature releases. Coexist with Fusion long-term.
  6. Migration — phased process, 2-6 недель для проекта 1000+ моделей. Phases: audit -> autofix -> local validation -> CI parallel -> canary production -> full production.
  7. Rollback ready на каждой phase. Production data infrastructure migrations требуют conservatism.

В следующем модуле (13) мы погружаемся в semantic layer internals — MetricFlow, DataflowPlan, v2 YAML spec, dbt MCP server.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Что делает dbt-autofix?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4