Skip to content

fix: apply only new or changed databricks_tags on table re-runs - #1572

Open
sd-db wants to merge 3 commits into
mainfrom
fix/issue-1308-table-tags-reapplied
Open

fix: apply only new or changed databricks_tags on table re-runs#1572
sd-db wants to merge 3 commits into
mainfrom
fix/issue-1308-table-tags-reapplied

Conversation

@sd-db

@sd-db sd-db commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Problem

For the table materialization, dbt re-applies every configured databricks_tags (table-level) and column-level databricks_tags on every run via ALTER … SET TAGS — one ALTER per column. When many columns are tagged this dominates run time (each SET TAGS is ~300ms) even when nothing changed.

Root cause

The set-only tag diff already exists (TagsConfig.get_diff / ColumnTagsConfig.get_diff) but is wired only into the incremental materialization. The table path applies all configured tags unconditionally on every run — both the v1/legacy path and the v2 create_table_at.

Fix

Reuse the existing diff on the table path. When an existing delta/iceberg table is replaced in place (CREATE OR REPLACE, which preserves tags), fetch the current server tags and apply only those that are new or changed. Fresh creates and drop+recreates apply all tags (no tags to diff against), and tag-free models skip the fetch entirely.

The diff is gated on replaced_in_place — an existing delta/iceberg table replaced in place — not merely on a relation having existed. A drop+recreate (a non-table type, or a non-delta/iceberg format) produces a fresh table with no inherited tags, so it must apply all configured tags rather than diff against possibly-stale metadata.

Tests

New tests/functional/adapter/tags/test_table_tag_fetch_skips.py:

  • a tag-free table never fetches tag metadata;
  • a re-run with table/column tags fetches to diff (v1 and v2 paths);
  • a dropped+recreated relation applies all tags without fetching.

Existing tag and incremental-metadata-fetch suites are unchanged and green.

Closes #1308

@sd-db
sd-db requested a review from jprakash-db as a code owner July 1, 2026 12:21
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  dbt/adapters/databricks
  impl.py 1161, 1168-1177, 1184-1193, 1197
Project Total  

This report was generated by python-coverage-comment-action

sd-db added 2 commits August 9, 2026 06:45
Address review gaps on the table tag-diff change:

- Assert a *changed* tag value still reaches the server on a re-run, for
  both table- and column-level tags. This is the diff path's one real
  failure mode and was previously uncovered; the existing tests only
  assert whether a metadata fetch occurred.
- Add a v2 `create_table_at` case for table-level tags. v2 coverage was
  column-tags only, and `use_materialization_v2` defaults to false, so the
  unmarked classes all exercise v1.
- Make `TestTableDropRecreateAppliesAllTags` rerun-safe. It rewrites a
  model via `write_file`, so without the mixin a `--reruns` retry inherits
  the converted table and stops testing view->table conversion.

Also link the PR in the changelog entry and describe the diff's gating
condition rather than naming file formats: `resolve_file_format` maps
`table_format='iceberg'` to delta or parquet, so it does not return the
literal 'iceberg' the gate tests for.
Resolves a conflict in `table.sql` between this branch's `replaced_in_place`
refactor and #1592, which added `is_shallow_clone` to the two drop conditions
that `replaced_in_place` negates.

Since a shallow clone's table type cannot be changed in place, it must be
dropped and recreated -- so it is not replaced in place and inherits no tags.
Folded the term into the predicate rather than into the drop sites, keeping
both as `not replaced_in_place`:

  replaced_in_place = existing_relation
      and not existing_relation.is_shallow_clone
      and existing_relation.type == 'table'
      and existing_relation.can_be_replaced
      and adapter.resolve_file_format(config) in ('delta', 'iceberg')

`can_be_replaced` alone does not cover this: it tests relation type plus
delta/iceberg provider, so a shallow clone of a delta table passes it.

Add `TestRebuildOverShallowCloneAppliesAllTags`, which covers the interaction
both changes touch: rebuilding a tagged table over a shallow clone must drop
the clone and apply all tags to the fresh table. Without the `is_shallow_clone`
term it fails on `MANAGED_SHALLOW_CLONE != MANAGED` -- i.e. it guards #1592's
fix, not only the tag diff.

Also move this branch's changelog entry to the 1.12.4 (TBD) section; the
automatic merge placed it under the already-released 1.12.2 heading.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Databricks_tags are set every run

2 participants