Migration: dbt-autofix и compatibility
В прошлых уроках мы поняли, что Fusion может ускорить ваш local dev и CI fast paths. Но как практически мигрировать существующий проект на 1000+ моделей? Здесь приходит dbt-autofix — инструмент, который dbt Labs разработал для автоматизации миграции на Fusion compatibility.
В этом уроке мы разберём:
- Что такое
dbt-autofix, зачем он нужен. - Какие конкретные изменения он делает в коде.
- Compatibility issues — что Fusion поддерживает, что нет (на 2026 год).
- Параллельная эксплуатация Fusion и dbt-core.
- 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:
Типичные изменения после 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+) использует
Пример 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
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.
Итого
- dbt-autofix автоматизирует большую часть миграции на Fusion. Изменения: macro dispatch syntax, semantic_models v1->v2, Iceberg catalog config, snapshot YAML conversion.
- Manual changes требуются для exotic Jinja, custom Python materializations, adapter-specific code.
- Compatibility matrix на 2026: основные сценарии работают; advanced/exotic — partial. Always test ваш конкретный use case.
- Параллельная эксплуатация — стандарт. Через pyenv/asdf, containers, или dbt Cloud CLI.
- dbt-core НЕ deprecated. 1.10, 1.11, 1.12 — active feature releases. Coexist with Fusion long-term.
- Migration — phased process, 2-6 недель для проекта 1000+ моделей. Phases: audit -> autofix -> local validation -> CI parallel -> canary production -> full production.
- Rollback ready на каждой phase. Production data infrastructure migrations требуют conservatism.
В следующем модуле (13) мы погружаемся в semantic layer internals — MetricFlow, DataflowPlan, v2 YAML spec, dbt MCP server.