Skip to content

Commit 6a1a6dc

Browse files
canbekleysd-db
authored andcommitted
feat: databricks_tags merge behavior
Signed-off-by: Can Bekleyici <can.bekleyici@deepl.com>
1 parent 8035fac commit 6a1a6dc

4 files changed

Lines changed: 36 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
- Fix catalog names with special characters (e.g., hyphens) not being quoted in `SHOW SCHEMAS` commands, causing `INVALID_IDENTIFIER` errors ([#1325](https://github.com/databricks/dbt-databricks/issues/1325))
4444
- Fix liquid clustering rendering on streaming table materialization [#1330](https://github.com/databricks/dbt-databricks/pull/1330)
4545

46+
### Under the Hood
47+
48+
- **BREAKING:** `databricks_tags` defined at different hierarchy levels (e.g. project-level and model-level) now merge additively instead of the child config completely replacing the parent.
49+
50+
4651
## dbt-databricks 1.11.5 (Feb 19, 2026)
4752

4853
### Fixes

dbt/adapters/databricks/impl.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from collections.abc import Iterable, Iterator
66
from concurrent.futures import Future
77
from contextlib import contextmanager
8-
from dataclasses import dataclass
8+
from dataclasses import dataclass, field
99
from importlib import metadata
1010
from multiprocessing.context import SpawnContext
1111
from typing import TYPE_CHECKING, Any, ClassVar, Generic, NamedTuple, Optional, Union, cast
@@ -29,7 +29,7 @@
2929
SparkAdapter,
3030
)
3131
from dbt_common.behavior_flags import BehaviorFlag
32-
from dbt_common.contracts.config.base import BaseConfig
32+
from dbt_common.contracts.config.base import BaseConfig, MergeBehavior
3333
from dbt_common.exceptions import DbtConfigError, DbtInternalError
3434
from dbt_common.utils import executor
3535
from dbt_common.utils.dict import AttrDict
@@ -176,7 +176,7 @@ class DatabricksConfig(AdapterConfig):
176176
options: Optional[dict[str, str]] = None
177177
merge_update_columns: Optional[str] = None
178178
merge_exclude_columns: Optional[str] = None
179-
databricks_tags: Optional[dict[str, str]] = None
179+
databricks_tags: Optional[dict[str, str]] = field(default=None, metadata=MergeBehavior.Update.meta())
180180
query_tags: Optional[str] = None
181181
tblproperties: Optional[dict[str, str]] = None
182182
zorder: Optional[Union[list[str], str]] = None

tests/functional/adapter/tags/fixtures.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@
1616
select cast(1 as bigint) as id, 'hello' as msg, 'blue' as color
1717
"""
1818

19+
tags_merged_sql = """
20+
{{ config(
21+
materialized = 'table',
22+
databricks_tags = {'c': 'd'},
23+
) }}
24+
25+
select cast(1 as bigint) as id, 'hello' as msg, 'blue' as color
26+
"""
27+
1928
streaming_table_tags_sql = """
2029
{{ config(
2130
materialized='streaming_table',

tests/functional/adapter/tags/test_databricks_tags.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,25 @@ def test_updated_tags(self, project):
6262
assert actual_tags == expected_tags
6363

6464

65+
@pytest.mark.skip_profile("databricks_cluster")
66+
class TestTableTagsMerged(BaseTestTags):
67+
68+
@pytest.fixture(scope="class")
69+
def models(self):
70+
return {"tags.sql": fixtures.tags_merged_sql}
71+
72+
@pytest.fixture(scope="class")
73+
def project_config_update(self):
74+
return {
75+
"models": {
76+
"+databricks_tags": {
77+
"a": "b",
78+
"c": "TO_BE_REPLACED_AT_MODEL_LEVEL",
79+
}
80+
}
81+
}
82+
83+
6584
@pytest.mark.skip_profile("databricks_cluster")
6685
class TestTableTagsUpdateViaAlter(BaseTestTagsUpdateViaAlter):
6786
pass

0 commit comments

Comments
 (0)