Skip to content
Open
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
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
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