diff --git a/.changes/unreleased/Fixes-20231107-174352.yaml b/.changes/unreleased/Fixes-20231107-174352.yaml new file mode 100644 index 000000000..80592758d --- /dev/null +++ b/.changes/unreleased/Fixes-20231107-174352.yaml @@ -0,0 +1,7 @@ +kind: Fixes +body: Fixed issue where materialized views were failing on re-run with minimal config + parameters +time: 2023-11-07T17:43:52.972135-05:00 +custom: + Author: "mikealfare" + Issue: "1007" diff --git a/dbt/adapters/bigquery/relation.py b/dbt/adapters/bigquery/relation.py index a689e76fc..c14dba238 100644 --- a/dbt/adapters/bigquery/relation.py +++ b/dbt/adapters/bigquery/relation.py @@ -84,9 +84,10 @@ def materialized_view_config_changeset( ) if new_materialized_view.partition != existing_materialized_view.partition: + # the existing PartitionConfig is not hashable, but since we need to do + # a full refresh either way, we don't need to provide a context config_change_collection.partition = BigQueryPartitionConfigChange( action=RelationConfigChangeAction.alter, - context=new_materialized_view.partition, ) if new_materialized_view.cluster != existing_materialized_view.cluster: @@ -95,7 +96,7 @@ def materialized_view_config_changeset( context=new_materialized_view.cluster, ) - if config_change_collection: + if config_change_collection.has_changes: return config_change_collection return None diff --git a/dbt/adapters/bigquery/relation_configs/_partition.py b/dbt/adapters/bigquery/relation_configs/_partition.py index 094e4f1c4..0d0ee23a1 100644 --- a/dbt/adapters/bigquery/relation_configs/_partition.py +++ b/dbt/adapters/bigquery/relation_configs/_partition.py @@ -152,7 +152,7 @@ def parse_bq_table(cls, table: BigQueryTable) -> Dict[str, Any]: @dataclass(frozen=True, eq=True, unsafe_hash=True) class BigQueryPartitionConfigChange(RelationConfigChange): - context: Optional[PartitionConfig] + context: Optional[Any] = None @property def requires_full_refresh(self) -> bool: diff --git a/tests/functional/adapter/materialized_view_tests/_files.py b/tests/functional/adapter/materialized_view_tests/_files.py index 1ee64269d..86714036a 100644 --- a/tests/functional/adapter/materialized_view_tests/_files.py +++ b/tests/functional/adapter/materialized_view_tests/_files.py @@ -67,3 +67,14 @@ record_valid_date from {{ ref('my_seed') }} """ + + +MY_MINIMAL_MATERIALIZED_VIEW = """ +{{ + config( + materialized = 'materialized_view', + ) +}} + +select * from {{ ref('my_seed') }} +""" diff --git a/tests/functional/adapter/materialized_view_tests/test_materialized_view.py b/tests/functional/adapter/materialized_view_tests/test_materialized_view.py index 7ca90983e..4e980c2e4 100644 --- a/tests/functional/adapter/materialized_view_tests/test_materialized_view.py +++ b/tests/functional/adapter/materialized_view_tests/test_materialized_view.py @@ -4,6 +4,7 @@ from dbt.tests.adapter.materialized_view.basic import MaterializedViewBasic from tests.functional.adapter.materialized_view_tests._mixin import BigQueryMaterializedViewMixin +from tests.functional.adapter.materialized_view_tests import _files class TestBigqueryMaterializedViewsBasic(BigQueryMaterializedViewMixin, MaterializedViewBasic): @@ -27,3 +28,26 @@ def test_materialized_view_only_updates_after_refresh( self, project, my_materialized_view, my_seed ): pass + + +class TestMaterializedViewRerun: + """ + This addresses: https://github.com/dbt-labs/dbt-bigquery/issues/1007 + + This effectively tests that defaults get properly set so that the run is idempotent. + If the defaults are not properly set, changes could appear when there are no changes + and cause unexpected scenarios. + """ + + @pytest.fixture(scope="class", autouse=True) + def models(self): + return {"my_minimal_materialized_view.sql": _files.MY_MINIMAL_MATERIALIZED_VIEW} + + @pytest.fixture(scope="class", autouse=True) + def seeds(self): + return {"my_seed.csv": _files.MY_SEED} + + def test_minimal_materialized_view_is_idempotent(self, project): + run_dbt(["seed"]) + run_dbt(["run"]) + run_dbt(["run"])