Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- Add support for Python UDFs ([#1336](https://github.com/databricks/dbt-databricks/pull/1336))
- Add support for key-only `databricks_tags` for table and column tagging. This can now be configured by setting tag values to empty strings `""` or `None`. ([#1339](https://github.com/databricks/dbt-databricks/pull/1339))

### Under the Hood

- **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.

## dbt-databricks 1.11.7 (Apr 17, 2026)

### Features
Expand Down
8 changes: 5 additions & 3 deletions dbt/adapters/databricks/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from collections.abc import Iterable, Iterator
from concurrent.futures import Future
from contextlib import contextmanager
from dataclasses import dataclass
from dataclasses import dataclass, field
from importlib import metadata
from multiprocessing.context import SpawnContext
from typing import TYPE_CHECKING, Any, ClassVar, Generic, NamedTuple, Optional, Union, cast
Expand All @@ -29,7 +29,7 @@
SparkAdapter,
)
from dbt_common.behavior_flags import BehaviorFlag
from dbt_common.contracts.config.base import BaseConfig
from dbt_common.contracts.config.base import BaseConfig, MergeBehavior
from dbt_common.exceptions import DbtConfigError, DbtInternalError
from dbt_common.utils import executor
from dbt_common.utils.dict import AttrDict
Expand Down Expand Up @@ -176,7 +176,9 @@ class DatabricksConfig(AdapterConfig):
options: Optional[dict[str, str]] = None
merge_update_columns: Optional[str] = None
merge_exclude_columns: Optional[str] = None
databricks_tags: Optional[dict[str, str]] = None
databricks_tags: Optional[dict[str, str]] = field(
default=None, metadata=MergeBehavior.Update.meta()
)
query_tags: Optional[str] = None
tblproperties: Optional[dict[str, str]] = None
zorder: Optional[Union[list[str], str]] = None
Expand Down
9 changes: 9 additions & 0 deletions tests/functional/adapter/tags/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@
select cast(1 as bigint) as id, 'hello' as msg, 'blue' as color
"""

tags_merged_sql = """
{{ config(
materialized = 'table',
databricks_tags = {'c': 'd', 'k': ''},
) }}

select cast(1 as bigint) as id, 'hello' as msg, 'blue' as color
"""

streaming_table_tags_sql = """
{{ config(
materialized='streaming_table',
Expand Down
18 changes: 18 additions & 0 deletions tests/functional/adapter/tags/test_databricks_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ def test_updated_tags(self, project):
assert actual_tags == expected_tags


@pytest.mark.skip_profile("databricks_cluster")
class TestTableTagsMerged(BaseTestTags):
@pytest.fixture(scope="class")
def models(self):
return {"tags.sql": fixtures.tags_merged_sql}

@pytest.fixture(scope="class")
def project_config_update(self):
return {
"models": {
"+databricks_tags": {
"a": "b",
"c": "TO_BE_REPLACED_AT_MODEL_LEVEL",
}
}
}


@pytest.mark.skip_profile("databricks_cluster")
class TestTableTagsUpdateViaAlter(BaseTestTagsUpdateViaAlter):
pass
Expand Down
Loading