From ee9016eda0b5da226b33043ae980cec511f42030 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 20 Jun 2024 16:52:41 -0700 Subject: [PATCH] Add CumulativeTypeParams to core parser --- core/dbt/artifacts/resources/v1/metric.py | 9 +++++ core/dbt/contracts/graph/unparsed.py | 13 ++++++- core/dbt/parser/schema_yaml_readers.py | 41 +++++++++++++++++++---- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/core/dbt/artifacts/resources/v1/metric.py b/core/dbt/artifacts/resources/v1/metric.py index 4f4dcfb98c9..87a56f4b2ba 100644 --- a/core/dbt/artifacts/resources/v1/metric.py +++ b/core/dbt/artifacts/resources/v1/metric.py @@ -6,6 +6,7 @@ from dbt_semantic_interfaces.type_enums import ( ConversionCalculationType, MetricType, + PeriodAggregation, TimeGranularity, ) @@ -80,6 +81,13 @@ class ConversionTypeParams(dbtClassMixin): constant_properties: Optional[List[ConstantPropertyInput]] = None +@dataclass +class CumulativeTypeParams(dbtClassMixin): + window: Optional[MetricTimeWindow] = None + grain_to_date: Optional[TimeGranularity] = None + period_agg: PeriodAggregation = PeriodAggregation.FIRST + + @dataclass class MetricTypeParams(dbtClassMixin): measure: Optional[MetricInputMeasure] = None @@ -91,6 +99,7 @@ class MetricTypeParams(dbtClassMixin): grain_to_date: Optional[TimeGranularity] = None metrics: Optional[List[MetricInput]] = None conversion_type_params: Optional[ConversionTypeParams] = None + cumulative_type_params: Optional[CumulativeTypeParams] = None @dataclass diff --git a/core/dbt/contracts/graph/unparsed.py b/core/dbt/contracts/graph/unparsed.py index f2fb390c69e..d463f4be709 100644 --- a/core/dbt/contracts/graph/unparsed.py +++ b/core/dbt/contracts/graph/unparsed.py @@ -4,7 +4,10 @@ from pathlib import Path from typing import Any, Dict, List, Literal, Optional, Sequence, Union -from dbt_semantic_interfaces.type_enums import ConversionCalculationType +from dbt_semantic_interfaces.type_enums import ( + ConversionCalculationType, + PeriodAggregation, +) # trigger the PathEncoder import dbt_common.helper_types # noqa:F401 @@ -532,6 +535,13 @@ class UnparsedConversionTypeParams(dbtClassMixin): constant_properties: Optional[List[ConstantPropertyInput]] = None +@dataclass +class UnparsedCumulativeTypeParams(dbtClassMixin): + window: Optional[str] = None + grain_to_date: Optional[str] = None + period_agg: str = PeriodAggregation.FIRST.value + + @dataclass class UnparsedMetricTypeParams(dbtClassMixin): measure: Optional[Union[UnparsedMetricInputMeasure, str]] = None @@ -542,6 +552,7 @@ class UnparsedMetricTypeParams(dbtClassMixin): grain_to_date: Optional[str] = None # str is really a TimeGranularity Enum metrics: Optional[List[Union[UnparsedMetricInput, str]]] = None conversion_type_params: Optional[UnparsedConversionTypeParams] = None + cumulative_type_params: Optional[UnparsedCumulativeTypeParams] = None @dataclass diff --git a/core/dbt/parser/schema_yaml_readers.py b/core/dbt/parser/schema_yaml_readers.py index 646de376763..5abb15eac76 100644 --- a/core/dbt/parser/schema_yaml_readers.py +++ b/core/dbt/parser/schema_yaml_readers.py @@ -6,11 +6,13 @@ DimensionType, EntityType, MetricType, + PeriodAggregation, TimeGranularity, ) from dbt.artifacts.resources import ( ConversionTypeParams, + CumulativeTypeParams, Dimension, DimensionTypeParams, Entity, @@ -42,6 +44,7 @@ from dbt.contracts.graph.nodes import Exposure, Group, Metric, SavedQuery, SemanticModel from dbt.contracts.graph.unparsed import ( UnparsedConversionTypeParams, + UnparsedCumulativeTypeParams, UnparsedDimension, UnparsedDimensionTypeParams, UnparsedEntity, @@ -221,9 +224,19 @@ def _get_input_measures( return input_measures - def _get_time_window( - self, - unparsed_window: Optional[str], + def _get_period_agg(self, unparsed_period_agg: str) -> Optional[PeriodAggregation]: + return PeriodAggregation(unparsed_period_agg) + + def _get_optional_grain_to_date( + self, unparsed_grain_to_date: Optional[str] + ) -> Optional[TimeGranularity]: + if not unparsed_grain_to_date: + return None + + return TimeGranularity(unparsed_grain_to_date) + + def _get_optional_time_window( + self, unparsed_window: Optional[str] ) -> Optional[MetricTimeWindow]: if unparsed_window is not None: parts = unparsed_window.split(" ") @@ -277,7 +290,7 @@ def _get_metric_input(self, unparsed: Union[UnparsedMetricInput, str]) -> Metric name=unparsed.name, filter=parse_where_filter(unparsed.filter), alias=unparsed.alias, - offset_window=self._get_time_window(unparsed.offset_window), + offset_window=self._get_optional_time_window(unparsed.offset_window), offset_to_grain=offset_to_grain, ) @@ -311,10 +324,21 @@ def _get_optional_conversion_type_params( conversion_measure=self._get_input_measure(unparsed.conversion_measure), entity=unparsed.entity, calculation=ConversionCalculationType(unparsed.calculation), - window=self._get_time_window(unparsed.window), + window=self._get_optional_time_window(unparsed.window), constant_properties=unparsed.constant_properties, ) + def _get_optional_cumulative_type_params( + self, unparsed: Optional[UnparsedCumulativeTypeParams] + ) -> Optional[CumulativeTypeParams]: + if unparsed is None: + return None + return CumulativeTypeParams( + window=self._get_optional_time_window(unparsed.window), + grain_to_date=self._get_optional_grain_to_date(unparsed.grain_to_date), + period_agg=self._get_period_agg(unparsed.period_agg), + ) + def _get_metric_type_params(self, type_params: UnparsedMetricTypeParams) -> MetricTypeParams: grain_to_date: Optional[TimeGranularity] = None if type_params.grain_to_date is not None: @@ -325,12 +349,15 @@ def _get_metric_type_params(self, type_params: UnparsedMetricTypeParams) -> Metr numerator=self._get_optional_metric_input(type_params.numerator), denominator=self._get_optional_metric_input(type_params.denominator), expr=str(type_params.expr) if type_params.expr is not None else None, - window=self._get_time_window(type_params.window), + window=self._get_optional_time_window(type_params.window), grain_to_date=grain_to_date, metrics=self._get_metric_inputs(type_params.metrics), conversion_type_params=self._get_optional_conversion_type_params( type_params.conversion_type_params - ) + ), + cumulative_type_params=self._get_optional_cumulative_type_params( + type_params.cumulative_type_params + ), # input measures are calculated via metric processing post parsing # input_measures=?, )