Skip to content

Commit

Permalink
Set default_grain in transformations, if not set in YAML
Browse files Browse the repository at this point in the history
  • Loading branch information
courtneyholcomb committed Jun 27, 2024
1 parent eaf37db commit 50fed79
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dbt_semantic_interfaces/implementations/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class PydanticMetric(HashableBaseModel, ModelWithMetadataParsing):
metadata: Optional[PydanticMetadata]
label: Optional[str] = None
config: Optional[PydanticMetricConfig]
default_grain: TimeGranularity = TimeGranularity.DAY
default_grain: Optional[TimeGranularity] = None

@property
def input_measures(self) -> Sequence[PydanticMetricInputMeasure]:
Expand Down
2 changes: 1 addition & 1 deletion dbt_semantic_interfaces/protocols/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def label(self) -> Optional[str]:

@property
@abstractmethod
def default_grain(self) -> TimeGranularity:
def default_grain(self) -> Optional[TimeGranularity]:
"""Default grain used for the metric.
This will be used in a couple of circumstances:
Expand Down
48 changes: 48 additions & 0 deletions dbt_semantic_interfaces/transformations/default_grain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from typing import Set

from typing_extensions import override

from dbt_semantic_interfaces.implementations.semantic_manifest import (
PydanticSemanticManifest,
)
from dbt_semantic_interfaces.protocols import ProtocolHint
from dbt_semantic_interfaces.references import (
DimensionReference,
TimeDimensionReference,
)
from dbt_semantic_interfaces.transformations.transform_rule import (
SemanticManifestTransformRule,
)
from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity


class SetDefaultGrainRule(ProtocolHint[SemanticManifestTransformRule[PydanticSemanticManifest]]):
"""If default_grain is not set for a metric, set it to DAY if available, else the smallest available grain."""

@override
def _implements_protocol(self) -> SemanticManifestTransformRule[PydanticSemanticManifest]: # noqa: D
return self

@staticmethod
def transform_model(semantic_manifest: PydanticSemanticManifest) -> PydanticSemanticManifest:
"""For each metric, set default_grain to DAY or the smallest granularity supported by all agg_time_dims."""
for metric in semantic_manifest.metrics:
if metric.default_grain:
continue

default_grain = TimeGranularity.DAY
seen_agg_time_dimensions: Set[TimeDimensionReference] = set()
for semantic_model in semantic_manifest.semantic_models:
for measure_ref in set(metric.measure_references).intersection(semantic_model.measure_references):
agg_time_dimension_ref = semantic_model.checked_agg_time_dimension_for_measure(measure_ref)
if agg_time_dimension_ref in seen_agg_time_dimensions:
continue
seen_agg_time_dimensions.add(agg_time_dimension_ref)
dimension = semantic_model.get_dimension(DimensionReference(agg_time_dimension_ref.element_name))
if (
dimension.type_params
and dimension.type_params.time_granularity.to_int() > default_grain.to_int()
):
default_grain = dimension.type_params.time_granularity

return semantic_manifest

0 comments on commit 50fed79

Please sign in to comment.