Skip to content

Commit 0a19506

Browse files
committed
Merge remote-tracking branch 'origin/1.12.latest' into fix/issue-1331-warehouse-only-parse-stub
2 parents abec7b5 + 3d210a6 commit 0a19506

30 files changed

Lines changed: 1904 additions & 106 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
- Add support for row filters ([#1294](https://github.com/databricks/dbt-databricks/pull/1294))
77
- Add support for Python UDFs ([#1336](https://github.com/databricks/dbt-databricks/pull/1336))
88
- 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))
9+
- Support `SCHEDULE EVERY` and `TRIGGER ON UPDATE` refresh modes for materialized views and streaming tables, with parser and diff coverage so relations whose actual refresh is not CRON no longer crash on subsequent runs ([#1293](https://github.com/databricks/dbt-databricks/issues/1293))
10+
11+
### Fixes
12+
13+
- Fix `RefreshConfig.__eq__` self/other typo where two configs with the same `cron` but different `time_zone_value` compared equal
14+
- Fix streaming-table DROP-SCHEDULE path that was silently filtered out of the changeset
915

1016
### Fixes
1117

@@ -18,6 +24,7 @@
1824
### Under the Hood
1925

2026
- **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.
27+
- Skip `information_schema.tags` and `information_schema.column_tags` metadata fetches when table tags and column tags are not configured on a model. ([#1387](https://github.com/databricks/dbt-databricks/pull/1387))
2128

2229
## dbt-databricks 1.11.8 (TBD)
2330

dbt/adapters/databricks/impl.py

Lines changed: 96 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@
8181
StreamingTableConfig,
8282
)
8383
from dbt.adapters.databricks.relation_configs.table_format import TableFormat
84+
from dbt.adapters.databricks.relation_configs.tags import (
85+
TagsProcessor,
86+
)
8487
from dbt.adapters.databricks.relation_configs.tblproperties import TblPropertiesConfig
8588
from dbt.adapters.databricks.relation_configs.view import ViewConfig
8689
from dbt.adapters.databricks.utils import (
@@ -987,17 +990,21 @@ def parse_columns_and_constraints(
987990
return enriched_columns, parsed_constraints
988991

989992
@available.parse(lambda *a, **k: {})
990-
def get_relation_config(self, relation: DatabricksRelation) -> DatabricksRelationConfigBase:
993+
def get_relation_config(
994+
self,
995+
relation: DatabricksRelation,
996+
model_config: Optional[DatabricksRelationConfigBase] = None,
997+
) -> DatabricksRelationConfigBase:
991998
if relation.type == DatabricksRelationType.MaterializedView:
992-
return MaterializedViewAPI.get_from_relation(self, relation)
999+
return MaterializedViewAPI.get_from_relation(self, relation, model_config)
9931000
elif relation.type == DatabricksRelationType.StreamingTable:
994-
return StreamingTableAPI.get_from_relation(self, relation)
1001+
return StreamingTableAPI.get_from_relation(self, relation, model_config)
9951002
elif relation.type == DatabricksRelationType.Table:
996-
return IncrementalTableAPI.get_from_relation(self, relation)
1003+
return IncrementalTableAPI.get_from_relation(self, relation, model_config)
9971004
elif relation.type == DatabricksRelationType.View:
998-
return ViewAPI.get_from_relation(self, relation)
1005+
return ViewAPI.get_from_relation(self, relation, model_config)
9991006
elif relation.type == DatabricksRelationType.MetricView:
1000-
return MetricViewAPI.get_from_relation(self, relation)
1007+
return MetricViewAPI.get_from_relation(self, relation, model_config)
10011008
else:
10021009
raise NotImplementedError(f"Relation type {relation.type} is not supported.")
10031010

@@ -1084,12 +1091,15 @@ def config_type(cls) -> type[DatabricksRelationConfig]:
10841091

10851092
@classmethod
10861093
def get_from_relation(
1087-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1094+
cls,
1095+
adapter: DatabricksAdapter,
1096+
relation: DatabricksRelation,
1097+
model_config: Optional[DatabricksRelationConfigBase] = None,
10881098
) -> DatabricksRelationConfig:
10891099
"""Get the relation config from the relation."""
10901100

10911101
assert relation.type == cls.relation_type
1092-
results = cls._describe_relation(adapter, relation)
1102+
results = cls._describe_relation(adapter, relation, model_config)
10931103
return cls.config_type().from_results(results)
10941104

10951105
@classmethod
@@ -1101,7 +1111,10 @@ def get_from_relation_config(cls, relation_config: RelationConfig) -> Databricks
11011111
@classmethod
11021112
@abstractmethod
11031113
def _describe_relation(
1104-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1114+
cls,
1115+
adapter: DatabricksAdapter,
1116+
relation: DatabricksRelation,
1117+
model_config: Optional[DatabricksRelationConfigBase] = None,
11051118
) -> RelationResults:
11061119
"""Describe the relation and return the results."""
11071120

@@ -1111,11 +1124,14 @@ def _describe_relation(
11111124
class DeltaLiveTableAPIBase(RelationAPIBase[DatabricksRelationConfig]):
11121125
@classmethod
11131126
def get_from_relation(
1114-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1127+
cls,
1128+
adapter: DatabricksAdapter,
1129+
relation: DatabricksRelation,
1130+
model_config: Optional[DatabricksRelationConfigBase] = None,
11151131
) -> DatabricksRelationConfig:
11161132
"""Get the relation config from the relation."""
11171133

1118-
relation_config = super().get_from_relation(adapter, relation)
1134+
relation_config = super().get_from_relation(adapter, relation, model_config)
11191135

11201136
# Ensure any current refreshes are completed before returning the relation config
11211137
tblproperties = cast(TblPropertiesConfig, relation_config.config["tblproperties"])
@@ -1135,7 +1151,10 @@ def config_type(cls) -> type[MaterializedViewConfig]:
11351151

11361152
@classmethod
11371153
def _describe_relation(
1138-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1154+
cls,
1155+
adapter: DatabricksAdapter,
1156+
relation: DatabricksRelation,
1157+
model_config: Optional[DatabricksRelationConfigBase] = None,
11391158
) -> RelationResults:
11401159
kwargs = {"table_name": relation}
11411160
results: RelationResults = dict()
@@ -1147,9 +1166,18 @@ def _describe_relation(
11471166
results["information_schema.views"] = get_first_row(
11481167
adapter.execute_macro("get_view_description", kwargs=kwargs)
11491168
)
1150-
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
11511169
results["show_tblproperties"] = adapter.execute_macro("fetch_tbl_properties", kwargs=kwargs)
1170+
1171+
# To be backward compatible model_config can be None. In that case, tags should be fetched
1172+
# to maintain backward compatibility.
1173+
table_tag_config = model_config.config.get(TagsProcessor.name) if model_config else None
1174+
if table_tag_config is None or table_tag_config.requires_server_metadata_for_diff():
1175+
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
1176+
else:
1177+
results["information_schema.tags"] = None
1178+
11521179
results["row_filters"] = adapter.execute_macro("fetch_row_filters", kwargs=kwargs)
1180+
11531181
return results
11541182

11551183

@@ -1162,7 +1190,10 @@ def config_type(cls) -> type[StreamingTableConfig]:
11621190

11631191
@classmethod
11641192
def _describe_relation(
1165-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1193+
cls,
1194+
adapter: DatabricksAdapter,
1195+
relation: DatabricksRelation,
1196+
model_config: Optional[DatabricksRelationConfigBase] = None,
11661197
) -> RelationResults:
11671198
kwargs = {"table_name": relation}
11681199
results: RelationResults = dict()
@@ -1186,16 +1217,37 @@ def config_type(cls) -> type[IncrementalTableConfig]:
11861217

11871218
@classmethod
11881219
def _describe_relation(
1189-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1220+
cls,
1221+
adapter: DatabricksAdapter,
1222+
relation: DatabricksRelation,
1223+
model_config: Optional[DatabricksRelationConfigBase] = None,
11901224
) -> RelationResults:
11911225
results = {}
11921226
kwargs = {"relation": relation}
11931227

11941228
if not relation.is_hive_metastore():
1195-
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
1196-
results["information_schema.column_tags"] = adapter.execute_macro(
1197-
"fetch_column_tags", kwargs=kwargs
1229+
# To be backward compatible model_config can be None. In that case, tags should be
1230+
# fetched to maintain backward compatibility.
1231+
table_tag_config = model_config.config.get(TagsProcessor.name) if model_config else None
1232+
if table_tag_config is None or table_tag_config.requires_server_metadata_for_diff():
1233+
results["information_schema.tags"] = adapter.execute_macro(
1234+
"fetch_tags", kwargs=kwargs
1235+
)
1236+
else:
1237+
results["information_schema.tags"] = None
1238+
1239+
# To be backward compatible model_config can be None. In that case, tags should be
1240+
# fetched to maintain backward compatibility.
1241+
column_tag_config = (
1242+
model_config.config.get(ColumnTagsProcessor.name) if model_config else None
11981243
)
1244+
if column_tag_config is None or column_tag_config.requires_server_metadata_for_diff():
1245+
results["information_schema.column_tags"] = adapter.execute_macro(
1246+
"fetch_column_tags", kwargs=kwargs
1247+
)
1248+
else:
1249+
results["information_schema.column_tags"] = None
1250+
11991251
results["non_null_constraint_columns"] = adapter.execute_macro(
12001252
"fetch_non_null_constraint_columns", kwargs=kwargs
12011253
)
@@ -1225,15 +1277,26 @@ def config_type(cls) -> type[ViewConfig]:
12251277

12261278
@classmethod
12271279
def _describe_relation(
1228-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1280+
cls,
1281+
adapter: DatabricksAdapter,
1282+
relation: DatabricksRelation,
1283+
model_config: Optional[DatabricksRelationConfigBase] = None,
12291284
) -> RelationResults:
12301285
results = {}
12311286
kwargs = {"relation": relation}
12321287

12331288
results["information_schema.views"] = get_first_row(
12341289
adapter.execute_macro("get_view_description", kwargs=kwargs)
12351290
)
1236-
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
1291+
1292+
# To be backward compatible model_config can be None. In that case, tags should be fetched
1293+
# to maintain backward compatibility.
1294+
table_tag_config = model_config.config.get(TagsProcessor.name) if model_config else None
1295+
if table_tag_config is None or table_tag_config.requires_server_metadata_for_diff():
1296+
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
1297+
else:
1298+
results["information_schema.tags"] = None
1299+
12371300
results["show_tblproperties"] = adapter.execute_macro("fetch_tbl_properties", kwargs=kwargs)
12381301

12391302
kwargs = {"table_name": relation}
@@ -1252,14 +1315,25 @@ def config_type(cls) -> type[MetricViewConfig]:
12521315

12531316
@classmethod
12541317
def _describe_relation(
1255-
cls, adapter: DatabricksAdapter, relation: DatabricksRelation
1318+
cls,
1319+
adapter: DatabricksAdapter,
1320+
relation: DatabricksRelation,
1321+
model_config: Optional[DatabricksRelationConfigBase] = None,
12561322
) -> RelationResults:
12571323
results = {}
12581324
kwargs = {"relation": relation}
1259-
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
12601325
results["show_tblproperties"] = adapter.execute_macro("fetch_tbl_properties", kwargs=kwargs)
1326+
1327+
kwargs = {"relation": relation}
1328+
table_tag_config = model_config.config.get(TagsProcessor.name) if model_config else None
1329+
if table_tag_config is None or table_tag_config.requires_server_metadata_for_diff():
1330+
results["information_schema.tags"] = adapter.execute_macro("fetch_tags", kwargs=kwargs)
1331+
else:
1332+
results["information_schema.tags"] = None
1333+
12611334
kwargs = {"table_name": relation}
12621335
results["describe_extended"] = adapter.execute_macro(
12631336
DESCRIBE_TABLE_EXTENDED_MACRO_NAME, kwargs=kwargs
12641337
)
1338+
12651339
return results

dbt/adapters/databricks/relation_configs/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ def get_diff(self, other: Self) -> Optional[Self]:
3434
return self
3535
return None
3636

37+
def requires_server_metadata_for_diff(self) -> bool:
38+
"""
39+
Indicates whether server metadata is required to compute the diff for this component.
40+
"""
41+
return True
42+
3743

3844
class DatabricksRelationChangeSet(BaseModel):
3945
"""Class for encapsulating the changes that need to be applied to a Databricks relation."""

dbt/adapters/databricks/relation_configs/column_tags.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ def get_diff(self, other: "ColumnTagsConfig") -> Optional["ColumnTagsConfig"]:
4141
return ColumnTagsConfig(set_column_tags=set_column_tags)
4242
return None
4343

44+
def requires_server_metadata_for_diff(self) -> bool:
45+
"""
46+
Indicates whether server metadata is required to compute the diff for this component.
47+
"""
48+
return self.set_column_tags is not None and len(self.set_column_tags) > 0
49+
4450

4551
class ColumnTagsProcessor(DatabricksComponentProcessor[ColumnTagsConfig]):
4652
name: ClassVar[str] = "column_tags"

0 commit comments

Comments
 (0)