From e6e4725525455f35a716570a7a24acc109a46daf Mon Sep 17 00:00:00 2001 From: Gerda Shank Date: Tue, 17 Dec 2024 15:47:08 -0500 Subject: [PATCH 1/3] Run check_modified_contract for modified_content --- core/dbt/graph/selector_methods.py | 13 ++++++++++--- .../defer_state/test_modified_state.py | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/core/dbt/graph/selector_methods.py b/core/dbt/graph/selector_methods.py index dbeaf7ed4c3..7c9306fc43d 100644 --- a/core/dbt/graph/selector_methods.py +++ b/core/dbt/graph/selector_methods.py @@ -680,17 +680,24 @@ def check_macros_modified(self, node): def check_modified_content( self, old: Optional[SelectorTarget], new: SelectorTarget, adapter_type: str ) -> bool: + different_contents = False if isinstance( new, (SourceDefinition, Exposure, Metric, SemanticModel, UnitTestDefinition, SavedQuery), ): # these all overwrite `same_contents` different_contents = not new.same_contents(old) # type: ignore - else: + elif new: # because we also pull in deleted/disabled nodes, this could be None different_contents = not new.same_contents(old, adapter_type) # type: ignore upstream_macro_change = self.check_macros_modified(new) - return different_contents or upstream_macro_change + + check_modified_contract = False + if isinstance(old, ModelNode): + func = self.check_modified_contract("same_contract", adapter_type) + check_modified_contract = func(old, new) + + return different_contents or upstream_macro_change or check_modified_contract def check_unmodified_content( self, old: Optional[SelectorTarget], new: SelectorTarget, adapter_type: str @@ -792,7 +799,7 @@ def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[Uniqu yield unique_id # checkers that can handle removed nodes - if checker.__name__ in ["check_modified_contract"]: + if checker.__name__ in ["check_modified_contract", "check_modified_content", "check_unmodified_content"]: # ignore included_nodes, since those cannot contain removed nodes for previous_unique_id, previous_node in manifest.nodes.items(): # detect removed (deleted, renamed, or disabled) nodes diff --git a/tests/functional/defer_state/test_modified_state.py b/tests/functional/defer_state/test_modified_state.py index 2ded38e742b..91fa0d4c45c 100644 --- a/tests/functional/defer_state/test_modified_state.py +++ b/tests/functional/defer_state/test_modified_state.py @@ -676,6 +676,15 @@ def test_delete_unversioned_contracted_model(self, project): assert expected_warning in logs assert expected_change in logs + # the same but for general-purpose state:modified + _, logs = run_dbt_and_capture( + ["run", "--models", "state:modified.contract", "--state", "./state"] + ) + expected_warning = "While comparing to previous project state, dbt detected a breaking change to an unversioned model" + expected_change = "Contracted model 'model.test.table_model' was deleted or renamed" + assert expected_warning in logs + assert expected_change in logs + class TestDeleteVersionedContractedModel(BaseModifiedState): MODEL_UNIQUE_ID = "model.test.table_model.v1" @@ -697,6 +706,14 @@ def test_delete_versioned_contracted_model(self, project): e.value ) + # the same but for general-purpose state:modified + with pytest.raises(ContractBreakingChangeError) as e: + run_dbt(["run", "--models", "state:modified", "--state", "./state"]) + + assert "Contracted model 'model.test.table_model.v1' was deleted or renamed." in str( + e.value + ) + class TestDisableUnversionedContractedModel(BaseModifiedState): MODEL_UNIQUE_ID = "model.test.table_model" From ff38472f2735317758f70de75fb453781a88de0c Mon Sep 17 00:00:00 2001 From: Gerda Shank Date: Tue, 17 Dec 2024 15:48:54 -0500 Subject: [PATCH 2/3] Changie --- .changes/unreleased/Fixes-20241217-154848.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Fixes-20241217-154848.yaml diff --git a/.changes/unreleased/Fixes-20241217-154848.yaml b/.changes/unreleased/Fixes-20241217-154848.yaml new file mode 100644 index 00000000000..fc6965547d4 --- /dev/null +++ b/.changes/unreleased/Fixes-20241217-154848.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: Run check_modified_contract for state:modified +time: 2024-12-17T15:48:48.053054-05:00 +custom: + Author: gshank + Issue: "11034" From 8e016054a30782e2f0329594ac3f47520c179033 Mon Sep 17 00:00:00 2001 From: Gerda Shank Date: Wed, 18 Dec 2024 14:23:26 -0500 Subject: [PATCH 3/3] Formatting --- core/dbt/graph/selector_methods.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/dbt/graph/selector_methods.py b/core/dbt/graph/selector_methods.py index 7c9306fc43d..3a774042b8d 100644 --- a/core/dbt/graph/selector_methods.py +++ b/core/dbt/graph/selector_methods.py @@ -799,7 +799,11 @@ def search(self, included_nodes: Set[UniqueId], selector: str) -> Iterator[Uniqu yield unique_id # checkers that can handle removed nodes - if checker.__name__ in ["check_modified_contract", "check_modified_content", "check_unmodified_content"]: + if checker.__name__ in [ + "check_modified_contract", + "check_modified_content", + "check_unmodified_content", + ]: # ignore included_nodes, since those cannot contain removed nodes for previous_unique_id, previous_node in manifest.nodes.items(): # detect removed (deleted, renamed, or disabled) nodes