Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Validate relation identifier length at creation time and raise a clear error when it exceeds Databricks' 255-character limit ([#1309](https://github.com/databricks/dbt-databricks/issues/1309))
- Fix spurious `MicrobatchConcurrency` behavior-change warning firing on every run regardless of whether the project contained microbatch models ([#1406](https://github.com/databricks/dbt-databricks/issues/1406))
- Fix DBR capability cache being permanently poisoned by a transient version-query failure ([#1398](https://github.com/databricks/dbt-databricks/issues/1398))
- Fix spurious `use_materialization_v2` behavior-change warning firing on table, view, seed, and incremental materializations ([#1089](https://github.com/databricks/dbt-databricks/issues/1089))

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

Expand Down
14 changes: 14 additions & 0 deletions dbt/adapters/databricks/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,20 @@ def _get_columns_for_catalog( # type: ignore[override]
as_dict["column_type"] = as_dict.pop("dtype")
yield as_dict

@available
def get_behavior_flag_no_warn(self, behavior_flag_name: str) -> bool:
"""Get the value of a behavior flag without triggering a warning.

dbt logs a warning the first time a behavior flag with a False value is accessed. Use
this method to access the value of a behavior flag without triggering a warning.

Decorated with `@available` so that Jinja macros can call it via the
`RuntimeDatabaseWrapper` exposed in the dbt runtime context.
"""
# As intended - This method will error out if the behavior flag is missing.
behavior_flag = getattr(self.behavior, behavior_flag_name)
return behavior_flag.no_warn

def add_query(
self,
sql: str,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
{% set is_replaceable_format = is_delta or is_iceberg %}
{% set compiled_code = adapter.clean_sql(model['compiled_code']) %}

{% if adapter.behavior.use_materialization_v2 %}
{% if adapter.get_behavior_flag_no_warn('use_materialization_v2') %}
{{ log("USING V2 MATERIALIZATION") }}
{#-- Set vars --#}
{% set safe_create = config.get('use_safer_relation_operations', False) | as_bool %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% materialization seed, adapter='databricks' %}
{% set target_relation = this.incorporate(type='table') %}

{% if adapter.behavior.use_materialization_v2 %}
{% if adapter.get_behavior_flag_no_warn('use_materialization_v2') %}
{{ create_seed_v2(target_relation) }}
{% else %}
{{ create_seed_v1(target_relation) }}
Expand Down
2 changes: 1 addition & 1 deletion dbt/include/databricks/macros/materializations/table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{% set target_relation = this.incorporate(type='table') %}
{% set compiled_code = adapter.clean_sql(compiled_code) %}

{% if adapter.behavior.use_materialization_v2 %}
{% if adapter.get_behavior_flag_no_warn('use_materialization_v2') %}
{% set intermediate_relation = make_intermediate_relation(target_relation) %}
{% set staging_relation = make_staging_relation(target_relation) %}

Expand Down
2 changes: 1 addition & 1 deletion dbt/include/databricks/macros/materializations/view.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{% set tags = config.get('databricks_tags') %}
{% set sql = adapter.clean_sql(sql) %}

{% if adapter.behavior.use_materialization_v2 %}
{% if adapter.get_behavior_flag_no_warn('use_materialization_v2') %}
{{ run_pre_hooks() }}
{% if existing_relation %}
{% if relation_should_be_altered(existing_relation) %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from dbt.tests.adapter.materialized_view import files
from dbt.tests.adapter.materialized_view.basic import MaterializedViewBasic

from dbt.adapters.databricks.impl import USE_MATERIALIZATION_V2
Comment thread
sd-db marked this conversation as resolved.
Outdated
from tests.functional.adapter.materialized_view_tests import fixtures


Expand Down Expand Up @@ -138,7 +139,6 @@ def test_materialized_view_complex_types(self, project):
)
assert results[0][1] == expected_struct_type


@pytest.mark.dlt
@pytest.mark.skip_profile("databricks_cluster", "databricks_uc_cluster")
class TestMaterializedViewLiquidClustering(TestMaterializedViewsMixin):
Expand Down
35 changes: 35 additions & 0 deletions tests/unit/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import pytest
from agate import Row
from dbt.config import RuntimeConfig
from dbt_common.events.event_manager_client import add_callback_to_manager
from dbt_common.exceptions import DbtConfigError, DbtDatabaseError, DbtValidationError

from dbt.adapters.databricks import DatabricksAdapter, __version__, constants
Expand Down Expand Up @@ -1351,3 +1352,37 @@ def test_is_uniform_with_invalid_materialization_error(
DbtConfigError, match="When table_format is 'iceberg', materialized must be"
):
adapter.is_uniform(mock_config)


class TestMaterializationV2BehaviorFlag(DatabricksAdapterBase):
"""The `use_materialization_v2` deprecation warning must not fire on every dbt run."""

@pytest.fixture
def adapter(self):
with patch("dbt.adapters.databricks.connections.DatabricksConnectionManager"):
return DatabricksAdapter(self._get_config(), get_context("spawn"))

@pytest.mark.parametrize("flag_value", [False, True])
def test_get_behavior_flag_no_warn_does_not_fire_event(self, adapter, flag_value):
"""The helper must return the flag value without firing
BehaviorChangeEvent for `use_materialization_v2`, regardless of value."""
adapter.behavior.use_materialization_v2.setting = flag_value

caught = []

def record(event_msg):
if (
event_msg.info.name == "BehaviorChangeEvent"
and event_msg.data.flag_name == "use_materialization_v2"
):
caught.append(event_msg)

add_callback_to_manager(record)

result = adapter.get_behavior_flag_no_warn("use_materialization_v2")

assert result == flag_value
assert caught == [], (
"get_behavior_flag_no_warn must not fire BehaviorChangeEvent for "
f"use_materialization_v2 (fired {len(caught)} times)"
)
Loading