Skip to content

Commit

Permalink
Set default_granularity properly for nested metrics (#304)
Browse files Browse the repository at this point in the history
### Description
Previously, this transformation was not setting default granularity
properly for metrics with input metrics (i.e., derived & ratio metrics).
This is because `Metric.measure_references` only gets the top-level
measures, not nested measures from input metrics. This PR fixes that bug
by utilizing `PydanticMetric.all_input_measures_for_metric()` instead.
Note that this feature (`default_granularity`) has not been released yet
so no customers should be impacted by this bug.

### Checklist

- [x] I have read [the contributing
guide](https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/CONTRIBUTING.md)
and understand what's expected of me
- [x] I have signed the
[CLA](https://docs.getdbt.com/docs/contributor-license-agreements)
- [x] This PR includes tests, or tests are not required/relevant for
this PR
- [ ] I have run `changie new` to [create a changelog
entry](https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/CONTRIBUTING.md#adding-a-changelog-entry)
  • Loading branch information
courtneyholcomb authored Jul 3, 2024
1 parent 6e67063 commit 7e65636
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
14 changes: 12 additions & 2 deletions dbt_semantic_interfaces/transformations/default_granularity.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from typing import Set
from typing import Dict, Set

from typing_extensions import override

from dbt_semantic_interfaces.implementations.metric import PydanticMetric
from dbt_semantic_interfaces.implementations.semantic_manifest import (
PydanticSemanticManifest,
)
from dbt_semantic_interfaces.protocols import ProtocolHint
from dbt_semantic_interfaces.protocols.metric import Metric
from dbt_semantic_interfaces.references import (
DimensionReference,
MetricReference,
TimeDimensionReference,
)
from dbt_semantic_interfaces.transformations.transform_rule import (
Expand All @@ -32,8 +35,15 @@ def transform_model(semantic_manifest: PydanticSemanticManifest) -> PydanticSema

default_granularity = TimeGranularity.DAY
seen_agg_time_dimensions: Set[TimeDimensionReference] = set()

metric_index: Dict[MetricReference, Metric] = {
MetricReference(metric.name): metric for metric in semantic_manifest.metrics
}

for semantic_model in semantic_manifest.semantic_models:
for measure_ref in set(metric.measure_references).intersection(semantic_model.measure_references):
for measure_ref in set(
PydanticMetric.all_input_measures_for_metric(metric=metric, metric_index=metric_index)
).intersection(semantic_model.measure_references):
try:
agg_time_dimension_ref = semantic_model.checked_agg_time_dimension_for_measure(measure_ref)
except AssertionError:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "dbt-semantic-interfaces"
version = "0.6.2"
version = "0.6.3"
description = 'The shared semantic layer definitions that dbt-core and MetricFlow use'
readme = "README.md"
requires-python = ">=3.8"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,32 @@ metric:
measure:
name: listings
filter: "{{ Metric('bookings', group_by=['listing', 'metric_time']) }} > 2"
---
metric:
name: monthly_bookings
description: bookings by month
label: bookings by month
type: simple
type_params:
measure:
name: monthly_bookings
---
metric:
name: yearly_bookings
description: bookings by year
label: bookings by year
type: simple
type_params:
measure:
name: yearly_bookings
---
metric:
name: monthly_times_yearly_bookings
description: monthly times yearly bookings
label: monthly times yearly bookings
type: derived
type_params:
expr: monthly_bookings * yearly_bookings
metrics:
- name: monthly_bookings
- name: yearly_bookings
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ semantic_model:
percentile: 0.99
use_discrete_percentile: true
use_approximate_percentile: true

- name: monthly_bookings
expr: "1"
agg: sum
agg_time_dimension: ds_monthly
- name: yearly_bookings
expr: "1"
agg: sum
agg_time_dimension: ds_yearly

dimensions:
- name: is_instant
Expand All @@ -83,6 +90,16 @@ semantic_model:
type: time
type_params:
time_granularity: day
- name: ds_monthly
type: time
expr: ds
type_params:
time_granularity: month
- name: ds_yearly
type: time
expr: ds
type_params:
time_granularity: year

primary_entity: booking

Expand Down
2 changes: 2 additions & 0 deletions tests/transformations/test_configurable_transform_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ def test_set_default_granularity_rule( # noqa: D
assert (
metric.default_granularity == configured_default_granularities[metric.name]
), f"Default granularity was unexpected changed during transformation for metric '{metric.name}"
if metric.name == "monthly_times_yearly_bookings":
assert metric.default_granularity == TimeGranularity.YEAR

0 comments on commit 7e65636

Please sign in to comment.