Skip to content

Commit e35ed6e

Browse files
Improve metric 'equality' check when searching
1 parent c35aa8f commit e35ed6e

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

dbt_semantic_interfaces/transformations/add_input_metric_measures.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ def _get_measures_for_metric(
3131
) -> Set[PydanticMetricInputMeasure]:
3232
"""Returns a unique set of input measures for a given metric."""
3333
measures: Set = set()
34-
matched_metric = next(
35-
iter((metric for metric in semantic_manifest.metrics if metric.name == metric_name)), None
36-
)
34+
matched_metric = next((metric for metric in semantic_manifest.metrics if metric.name == metric_name), None)
3735
if matched_metric:
3836
if matched_metric.type is MetricType.SIMPLE or matched_metric.type is MetricType.CUMULATIVE:
3937
if matched_metric.type_params.measure is not None:

dbt_semantic_interfaces/transformations/measure_to_metric_transformation_pieces/measure_features_to_metric_name.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,29 @@ def _find_metric_clone_in_manifest(
6666
but let's not prematurely optimize.
6767
"""
6868
search_metric = metric.copy(deep=True)
69+
original_input_measures = search_metric.type_params.input_measures
70+
original_measure = search_metric.type_params.measure
6971
for existing_metric in manifest.metrics:
7072
# this allows us to a straight equality comparison, which is safer in the future
7173
# than implementing a custom comparison function.
7274
search_metric.name = existing_metric.name
75+
search_metric.description = existing_metric.description
76+
search_metric.label = existing_metric.label
7377
search_metric.metadata = existing_metric.metadata
7478
search_metric.type_params.is_private = existing_metric.type_params.is_private
79+
search_metric.config = existing_metric.config
80+
# this is used for compatibility between new and old style metrics; we need to
81+
# match if the search input measures are empty (new-style) or if they match
82+
# the old-style input measures.
83+
if len(existing_metric.type_params.input_measures) == 0:
84+
search_metric.type_params.input_measures = []
85+
else:
86+
search_metric.type_params.input_measures = original_input_measures
87+
if existing_metric.type_params.measure is None:
88+
search_metric.type_params.measure = None
89+
else:
90+
search_metric.type_params.measure = original_measure
91+
7592
if search_metric == existing_metric:
7693
return existing_metric
7794
print("provided metric", search_metric)
@@ -178,6 +195,10 @@ def get_or_create_metric_for_measure(
178195
fill_nulls_with=fill_nulls_with,
179196
join_to_timespine=join_to_timespine,
180197
)
198+
# supporting legacy cases. Remove when we can remove input measures.
199+
built_metric.type_params.measure = PydanticMetricInputMeasure(name=measure.name)
200+
built_metric.type_params.input_measures = [PydanticMetricInputMeasure(name=measure.name)]
201+
181202
metric = self._find_metric_clone_in_manifest(
182203
metric=built_metric,
183204
manifest=manifest,

dbt_semantic_interfaces/transformations/proxy_measure.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def transform_model(semantic_manifest: PydanticSemanticManifest) -> PydanticSema
6262
)
6363
metric.name = measure.name
6464
metric.type_params.measure = PydanticMetricInputMeasure(name=measure.name)
65+
# metric.type_params.input_measures.append(metric.type_params.measure)
6566
semantic_manifest.metrics.append(metric)
6667

6768
return semantic_manifest

tests/parsing/test_metric_parsing_with_custom_grain.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def test_cumulative_metric_with_custom_grain_to_date() -> None: # noqa: D
4848
type_params:
4949
measure:
5050
name: bookings
51+
fill_nulls_with: 15
5152
cumulative_type_params:
5253
grain_to_date: martian_week
5354
"""
@@ -121,9 +122,9 @@ def test_cumulative_metric_with_custom_window() -> None: # noqa: D
121122
)
122123
assert not model.issues.has_blocking_issues
123124
semantic_manifest = model.semantic_manifest
124-
# 2 explicit ones and one that is created for the measure input for the
125-
# cumulative metric's params
126-
assert len(semantic_manifest.metrics) == 3
125+
# 2 explicit metrics. The cumulative metric's input metric should be deduplicated
126+
# so it will match.
127+
assert len(semantic_manifest.metrics) == 2
127128

128129
metric = next((m for m in semantic_manifest.metrics if m.name == "test_cumulative_metric_with_custom_window"), None)
129130
assert metric is not None, "Can't find metric"
@@ -185,9 +186,9 @@ def test_conversion_metric_with_custom_grain_window() -> None: # noqa: D
185186
)
186187
assert not model.issues.has_blocking_issues
187188
semantic_manifest = model.semantic_manifest
188-
# 2 explicit ones and one that is created for the measure input for the
189-
# cumulative metric's params
190-
assert len(semantic_manifest.metrics) == 3
189+
# 2 explicitly created metrics. The conversion measure -> metric transformation
190+
# should not need to create a new metric since the existing one already matches.
191+
assert len(semantic_manifest.metrics) == 2
191192

192193
metric = next(
193194
(m for m in semantic_manifest.metrics if m.name == "test_conversion_metric_with_custom_grain_window"), None

0 commit comments

Comments
 (0)