Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CumulativeTypeParams & sub-daily granularities to semantic manifest #10350

Merged
merged 11 commits into from
Jul 1, 2024
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20240625-095107.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Support cumulative_type_params & sub-daily granularities in semantic manifest.
time: 2024-06-25T09:51:07.983248-07:00
custom:
Author: courtneyholcomb
Issue: "10360"
1 change: 1 addition & 0 deletions core/dbt/artifacts/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from dbt.artifacts.resources.v1.metric import (
ConstantPropertyInput,
ConversionTypeParams,
CumulativeTypeParams,
Metric,
MetricConfig,
MetricInput,
Expand Down
9 changes: 9 additions & 0 deletions core/dbt/artifacts/resources/v1/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from dbt_semantic_interfaces.type_enums import (
ConversionCalculationType,
MetricType,
PeriodAggregation,
TimeGranularity,
)

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion core/dbt/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## Artifacts

### Generating JSON schemas
A helper script, `sripts/collect-artifact-schema.py` is available to generate json schemas corresponding to versioned artifacts (`ArtifactMixin`s).
A helper script, `scripts/collect-artifact-schema.py` is available to generate json schemas corresponding to versioned artifacts (`ArtifactMixin`s).

This script is necessary to run when a new artifact schema version is created, or when changes are made to existing artifact versions, and writes json schema to `schema/dbt/<artifact>/v<version>.json`.

Expand Down
13 changes: 12 additions & 1 deletion core/dbt/contracts/graph/unparsed.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
71 changes: 62 additions & 9 deletions core/dbt/parser/schema_yaml_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
DimensionType,
EntityType,
MetricType,
PeriodAggregation,
TimeGranularity,
)

from dbt.artifacts.resources import (
ConversionTypeParams,
CumulativeTypeParams,
Dimension,
DimensionTypeParams,
Entity,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -221,9 +224,19 @@

return input_measures

def _get_time_window(
self,
unparsed_window: Optional[str],
def _get_period_agg(self, unparsed_period_agg: str) -> PeriodAggregation:
return PeriodAggregation(unparsed_period_agg)

Check warning on line 228 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L228

Added line #L228 was not covered by tests

def _get_optional_grain_to_date(
self, unparsed_grain_to_date: Optional[str]
) -> Optional[TimeGranularity]:
if not unparsed_grain_to_date:
return None

Check warning on line 234 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L233-L234

Added lines #L233 - L234 were not covered by tests

return TimeGranularity(unparsed_grain_to_date)

Check warning on line 236 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L236

Added line #L236 was not covered by tests

def _get_optional_time_window(
self, unparsed_window: Optional[str]
) -> Optional[MetricTimeWindow]:
if unparsed_window is not None:
parts = unparsed_window.split(" ")
Expand Down Expand Up @@ -277,7 +290,7 @@
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,
)

Expand Down Expand Up @@ -311,11 +324,48 @@
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_metric_type_params(self, type_params: UnparsedMetricTypeParams) -> MetricTypeParams:
def _get_optional_cumulative_type_params(
self, unparsed_metric: UnparsedMetric
) -> Optional[CumulativeTypeParams]:
unparsed_type_params = unparsed_metric.type_params
if unparsed_metric.type.lower() == MetricType.CUMULATIVE.value:
if not unparsed_type_params.cumulative_type_params:
unparsed_type_params.cumulative_type_params = UnparsedCumulativeTypeParams()

Check warning on line 337 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L336-L337

Added lines #L336 - L337 were not covered by tests

if (

Check warning on line 339 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L339

Added line #L339 was not covered by tests
unparsed_type_params.window
and not unparsed_type_params.cumulative_type_params.window
):
unparsed_type_params.cumulative_type_params.window = unparsed_type_params.window
if (

Check warning on line 344 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L343-L344

Added lines #L343 - L344 were not covered by tests
unparsed_type_params.grain_to_date
and not unparsed_type_params.cumulative_type_params.grain_to_date
):
unparsed_type_params.cumulative_type_params.grain_to_date = (

Check warning on line 348 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L348

Added line #L348 was not covered by tests
unparsed_type_params.grain_to_date
)

return CumulativeTypeParams(

Check warning on line 352 in core/dbt/parser/schema_yaml_readers.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/schema_yaml_readers.py#L352

Added line #L352 was not covered by tests
window=self._get_optional_time_window(
unparsed_type_params.cumulative_type_params.window
),
grain_to_date=self._get_optional_grain_to_date(
unparsed_type_params.cumulative_type_params.grain_to_date
),
period_agg=self._get_period_agg(
unparsed_type_params.cumulative_type_params.period_agg
),
)

return None

def _get_metric_type_params(self, unparsed_metric: UnparsedMetric) -> MetricTypeParams:
type_params = unparsed_metric.type_params

grain_to_date: Optional[TimeGranularity] = None
if type_params.grain_to_date is not None:
grain_to_date = TimeGranularity(type_params.grain_to_date)
Expand All @@ -325,12 +375,15 @@
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(
unparsed_metric=unparsed_metric,
),
# input measures are calculated via metric processing post parsing
# input_measures=?,
)
Expand Down Expand Up @@ -380,7 +433,7 @@
description=unparsed.description,
label=unparsed.label,
type=MetricType(unparsed.type),
type_params=self._get_metric_type_params(unparsed.type_params),
type_params=self._get_metric_type_params(unparsed),
filter=parse_where_filter(unparsed.filter),
meta=unparsed.meta,
tags=unparsed.tags,
Expand Down
2 changes: 1 addition & 1 deletion core/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
# Accept patches but avoid automatically updating past a set minor version range.
"dbt-extractor>=0.5.0,<=0.6",
"minimal-snowplow-tracker>=0.0.2,<0.1",
"dbt-semantic-interfaces>=0.5.1,<0.7",
"dbt-semantic-interfaces>=0.6.1,<0.7",
# Minor versions for these are expected to be backwards-compatible
"dbt-common>=1.3.0,<2.0",
"dbt-adapters>=1.1.1,<2.0",
Expand Down
2 changes: 1 addition & 1 deletion schemas/dbt/catalog/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"dbt_version": {
"type": "string",
"default": "1.8.0a1"
"default": "1.9.0a1"
Copy link
Contributor

@QMalcolm QMalcolm Jun 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MichelleArk / @ChenyuLInx This looks correct to me, but I don't know if there'd be any fall out from doing so. This seem okay?

},
"generated_at": {
"type": "string"
Expand Down
Loading
Loading