Обновление packages: версионирование и breaking changes
Когда dbt-проект растёт, packages становятся критической зависимостью. dbt_utils, dbt_expectations, codegen используются в десятках мест. Если в new version что-то изменилось — пайплайн может сломаться.
Этот урок — про процесс обновления packages: как читать changelog, как обновлять, как тестировать.
Semantic versioning
Большинство dbt-packages следуют semantic versioning — формат MAJOR.MINOR.PATCH:
| Часть | Когда меняется | Пример |
|---|---|---|
| MAJOR | Breaking changes. API не совместим со старой версией. | 1.0.0 -> 2.0.0 |
| MINOR | New features, обратно-совместимые. | 1.3.0 -> 1.4.0 |
| PATCH | Bug fixes, обратно-совместимые. | 1.3.0 -> 1.3.1 |
В packages.yml:
packages:
- package: dbt-labs/dbt_utils
version: 1.3.0 # exact (рекомендуется)
- package: calogica/dbt_expectations
version: [">=0.10.0", "<0.11.0"] # range (мажор фиксирован)
Best practice: exact version в production. Range — для разработки/exploration.
Что в changelog
Перед обновлением — прочитайте changelog. Это обычно CHANGELOG.md в репозитории пакета. Для dbt_utils: https://github.com/dbt-labs/dbt-utils/blob/main/CHANGELOG.md.
Типичный changelog:
# dbt_utils 1.3.0 (2024-12-15)
## Breaking Changes
- Removed deprecated `dbt_utils.surrogate_key()` (use `generate_surrogate_key`)
- `dbt_utils.star` теперь требует dbt-core >= 1.5.0
## Features
- Added `dbt_utils.deduplicate` macro
- `pivot()` now supports custom separator
## Fixes
- Fix `date_spine` on BigQuery for leap years
- Better error message in `unique_combination_of_columns`
Что искать:
- Breaking changes — что нужно поправить в проекте.
- Deprecated — что нужно мигрировать (даже если ещё работает).
- Required dbt-core version — может ли пакет работать с вашей версией.
Reading deprecation warnings
dbt пишет warnings при использовании deprecated функций. Например:
$ dbt run
WARNING: dbt_utils.surrogate_key is deprecated. Use dbt_utils.generate_surrogate_key instead.
Found in: models/marts/dim_customers.sql:5
Эти warnings — first signal что нужно update код. Если их игнорировать — следующая major version пакета удалит deprecated, и проект упадёт.
Best practice: relay warnings in PR review. Любая новая deprecated warning — не merge, фикс.
Обновление: dbt deps —upgrade
# Apply versions from packages.yml + update package-lock.yml
dbt deps
# Force update — игнорирует lock-файл, тянет latest matching versions
dbt deps --upgrade
dbt deps --upgrade особенно полезен, если у вас в packages.yml:
- package: dbt-labs/dbt_utils
version: [">=1.0.0", "<2.0.0"]
Без --upgrade: dbt deps читает lock и устанавливает версию из lock (например 1.0.5).
С --upgrade: dbt deps игнорирует lock, резолвит latest matching (например 1.3.2). Lock обновляется.
В практике:
- Локально:
dbt deps --upgradeдля обновления версий. - CI:
dbt deps(без флага) — читает lock, всем одинаковые версии.
После dbt deps --upgrade — закоммитьте новый package-lock.yml в git.
Процесс обновления: пошаговый
Допустим, вы хотите обновить dbt_utils с 1.0.0 до 1.3.0.
Шаг 1: Прочитать changelog
Открыть CHANGELOG.md dbt_utils. Прочитать все entries между 1.0 и 1.3:
- Что breaking?
- Что deprecated?
- Какие new features (могут быть полезны)?
Шаг 2: Update packages.yml
# До:
- package: dbt-labs/dbt_utils
version: 1.0.0
# После:
- package: dbt-labs/dbt_utils
version: 1.3.0
Шаг 3: dbt deps
dbt deps --upgrade
Может появиться warning о conflicts с другими пакетами. Resolve через обновление их версий тоже.
Шаг 4: Run full test suite
dbt build
dbt build запускает всё: models, tests, snapshots, seeds. Если breaking change что-то ломает — поймаете.
Шаг 5: Investigate failures
Что часто ломается:
| Тип проблемы | Симптом | Решение |
|---|---|---|
| Deprecated macro | compilation error: macro 'surrogate_key' not found | Заменить на generate_surrogate_key |
| Changed signature | unexpected argument 'foo' | Прочитать docs new version, обновить вызовы |
| Removed config | config 'bar' is no longer supported | Migrate config to new format |
| dbt-core incompatible | package requires dbt-core >= 1.5, you have 1.3 | Сначала обновить dbt-core, затем package |
Шаг 6: Update код
Например, заменить surrogate_key на generate_surrogate_key:
-- До:
{{ dbt_utils.surrogate_key(['customer_id', 'order_id']) }}
-- После:
{{ dbt_utils.generate_surrogate_key(['customer_id', 'order_id']) }}
Используйте grep или sed для massive find/replace:
grep -rn "dbt_utils.surrogate_key" models/
# Найдите все вхождения, замените
# Или autoреплейс (осторожно с backup):
find models/ -name "*.sql" -exec sed -i.bak 's/dbt_utils.surrogate_key/dbt_utils.generate_surrogate_key/g' {} \;
Шаг 7: Rerun build + tests
dbt clean # очистить старые artifacts
dbt deps
dbt build
Если всё passes — обновление успешно.
Шаг 8: Commit + PR
git add packages.yml package-lock.yml models/
git commit -m "Update dbt_utils to 1.3.0"
git push origin update-dbt-utils
# -> PR
В PR description — обычно описывают breaking changes и rationale.
Известные breaking changes (2026 baseline)
dbt_utils
| From | To | Breaking |
|---|---|---|
| 0.x | 1.0 | Removed compatibility with dbt-core менее 1.0. Renamed surrogate_key -> generate_surrogate_key (alias kept). |
| 1.0 | 1.1 | None significant. |
| 1.1 | 1.2 | Removed dbt_utils.except (use SQL EXCEPT). |
| 1.2 | 1.3 | dbt_utils.pivot syntax changes for null handling. |
dbt_expectations
| From | To | Breaking |
|---|---|---|
| 0.7.x | 0.8.x | Renamed several test names; dropped support for dbt менее 1.3. |
| 0.8.x | 0.9.x | New parametrize syntax for some tests; old syntax raises error. |
| 0.9.x | 0.10.x | Drop dbt-core менее 1.7 support. Some tests now require additional macros. |
Прочтите конкретный changelog перед мажорным upgrade.
Compatibility матрица
На момент 2026:
| Package | Latest version | dbt-core compatibility |
|---|---|---|
| dbt-labs/dbt_utils | 1.3.x | не меньше 1.5.0 |
| calogica/dbt_expectations | 0.10.x | не меньше 1.7.0 |
| dbt-labs/codegen | 0.13.x | не меньше 1.5.0 |
| dbt-labs/audit_helper | 0.12.x | не меньше 1.5.0 |
| dbt-labs/dbt_external_tables | 0.10.x | не меньше 1.5.0 |
dbt-core 1.10 — все актуальные пакеты совместимы.
CI: автоматическое тестирование обновлений
Используйте Dependabot или Renovate для авто-PR с обновлениями:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
Для dbt packages есть отдельные tools, например:
- dbt-bouncer — для квалити чеков.
- Custom GitHub Actions, которые читают packages.yml + проверяют новые версии.
Альтернатива: manually обновлять раз в квартал. Это плохо для security patches, но в практике работает в маленьких командах.
Антипаттерны обновлений
Реальный package-lock.yml пример
Что в нём после dbt deps:
# package-lock.yml (генерируется dbt 1.7+)
packages:
- package: dbt-labs/dbt_utils
version: 1.3.0
- package: calogica/dbt_expectations
version: 0.10.4
- git: https://github.com/dbt-labs/codegen.git
revision: 0fa6bfe3ee04b6c0d9b65e30c70f3f81a8d80b6c # exact commit SHA
sha1_hash: 8a2f3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a
Что замечается:
- Hub-пакеты — фиксируется exact version.
- Git-пакеты — фиксируется exact commit SHA (даже если в packages.yml был tag).
- sha1_hash — целостность lock-файла.
После обновления dbt deps --upgrade:
# Новый package-lock.yml
packages:
- package: dbt-labs/dbt_utils
version: 1.3.2 # был 1.3.0, теперь 1.3.2
- package: calogica/dbt_expectations
version: 0.10.4
...
Только что изменилось — обновилась версия. CI на всех будет получать одинаковые.
Попробуй сам
В вашем dbt-проекте:
- Установите dbt_utils 1.0.0 (старая версия):
packages:
- package: dbt-labs/dbt_utils
version: 1.0.0
dbt deps
cat package-lock.yml # увидите 1.0.0
- Используйте deprecated
surrogate_keyв модели:
-- models/test_macro.sql
SELECT {{ dbt_utils.surrogate_key(['customer_id', 'order_id']) }} AS sk
FROM {{ ref('stg_jaffle__orders') }}
dbt run --select test_macro
# Может пройти с warning или success — зависит от версии
- Обновите до 1.3.0:
packages:
- package: dbt-labs/dbt_utils
version: 1.3.0
dbt deps --upgrade
cat package-lock.yml # теперь 1.3.0
- Перезапустите test_macro:
dbt run --select test_macro
# WARNING: dbt_utils.surrogate_key is deprecated...
- Migrate к новому имени:
SELECT {{ dbt_utils.generate_surrogate_key(['customer_id', 'order_id']) }} AS sk
dbt run --select test_macro # теперь без warning
Это миниатюра реального процесса update. На production-проекте — то же самое, но на 50+ файлах.
Ключевые выводы
- Semantic versioning (MAJOR.MINOR.PATCH). Major — breaking, minor — features, patch — fixes.
- packages.yml: exact version в production. Range
[">=1.0.0", "менее 2.0.0"]с upper bound для гибкости. - package-lock.yml (1.7+) — фиксирует exact versions. Коммитьте в git — все получают одно.
dbt deps— apply из lock.dbt deps --upgrade— игнорирует lock, latest matching.- Процесс обновления: changelog -> packages.yml -> dbt deps —upgrade -> dbt build -> fix breakings -> commit.
- Deprecation warnings — first signal. Migrate в момент появления, не накапливайте.
- Антипаттерны: update без changelog, range без upper bound, скип патч-версий, combine update с feature work в одном PR.
- Автоматизация: Dependabot / Renovate для auto-PR с updates.