Skip to content

Commit 217703e

Browse files
General clean up (in progress)
1 parent e35ed6e commit 217703e

File tree

4 files changed

+229
-4
lines changed

4 files changed

+229
-4
lines changed

dbt_semantic_interfaces/implementations/metric.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ def build_metric_aggregation_params(
350350
return PydanticMetricAggregationParams(
351351
semantic_model=semantic_model_name,
352352
agg=measure.agg,
353+
# TODO: clone this
353354
agg_params=measure.agg_params,
354355
agg_time_dimension=measure.agg_time_dimension,
355356
non_additive_dimension=measure.non_additive_dimension,

dbt_semantic_interfaces/transformations/measure_to_metric_transformation_pieces/measure_features_to_metric_name.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ def _find_metric_clone_in_manifest(
9191

9292
if search_metric == existing_metric:
9393
return existing_metric
94-
print("provided metric", search_metric)
95-
print("existing metric", existing_metric)
9694
return None
9795

9896
@staticmethod
@@ -101,7 +99,7 @@ def build_metric_from_measure_configuration(
10199
semantic_model_name: str,
102100
fill_nulls_with: Optional[int],
103101
join_to_timespine: Optional[bool],
104-
is_private: bool = True,
102+
is_private: bool,
105103
) -> PydanticMetric:
106104
"""Build a metric from the measure configuration.
107105
@@ -194,6 +192,7 @@ def get_or_create_metric_for_measure(
194192
semantic_model_name=model_name,
195193
fill_nulls_with=fill_nulls_with,
196194
join_to_timespine=join_to_timespine,
195+
is_private=True,
197196
)
198197
# supporting legacy cases. Remove when we can remove input measures.
199198
built_metric.type_params.measure = PydanticMetricInputMeasure(name=measure.name)

dbt_semantic_interfaces/transformations/proxy_measure.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ 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)
6665
semantic_manifest.metrics.append(metric)
6766

6867
return semantic_manifest
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
from dbt_semantic_interfaces.implementations.elements.dimension import (
2+
PydanticDimension,
3+
PydanticDimensionTypeParams,
4+
)
5+
from dbt_semantic_interfaces.implementations.elements.entity import PydanticEntity
6+
from dbt_semantic_interfaces.implementations.elements.measure import PydanticMeasure
7+
from dbt_semantic_interfaces.implementations.metric import (
8+
PydanticCumulativeTypeParams,
9+
PydanticMetric,
10+
PydanticMetricInput,
11+
PydanticMetricInputMeasure,
12+
PydanticMetricTimeWindow,
13+
PydanticMetricTypeParams,
14+
)
15+
from dbt_semantic_interfaces.implementations.node_relation import PydanticNodeRelation
16+
from dbt_semantic_interfaces.implementations.project_configuration import (
17+
PydanticProjectConfiguration,
18+
)
19+
from dbt_semantic_interfaces.implementations.semantic_manifest import (
20+
PydanticSemanticManifest,
21+
)
22+
from dbt_semantic_interfaces.implementations.semantic_model import (
23+
PydanticSemanticModel,
24+
PydanticSemanticModelDefaults,
25+
)
26+
from dbt_semantic_interfaces.transformations.semantic_manifest_transformer import (
27+
PydanticSemanticManifestTransformer,
28+
)
29+
from dbt_semantic_interfaces.type_enums import (
30+
AggregationType,
31+
DimensionType,
32+
EntityType,
33+
MetricType,
34+
TimeGranularity,
35+
)
36+
from dbt_semantic_interfaces.validations.semantic_manifest_validator import (
37+
SemanticManifestValidator,
38+
)
39+
40+
41+
def _project_config() -> PydanticProjectConfiguration:
42+
return PydanticProjectConfiguration()
43+
44+
45+
def _build_semantic_model_with_creatable_measure(
46+
sm_name: str,
47+
time_dim_name: str = "ds",
48+
) -> PydanticSemanticModel:
49+
return PydanticSemanticModel(
50+
name=sm_name,
51+
defaults=PydanticSemanticModelDefaults(agg_time_dimension=time_dim_name),
52+
node_relation=PydanticNodeRelation(alias=sm_name, schema_name="schema"),
53+
entities=[
54+
PydanticEntity(
55+
name="user",
56+
type=EntityType.PRIMARY,
57+
expr="user_id",
58+
),
59+
],
60+
dimensions=[
61+
PydanticDimension(
62+
name="ds",
63+
type=DimensionType.TIME,
64+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.DAY),
65+
),
66+
PydanticDimension(
67+
name="created_at",
68+
type=DimensionType.TIME,
69+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.DAY),
70+
),
71+
PydanticDimension(
72+
name="ds_partitioned",
73+
type=DimensionType.TIME,
74+
is_partition=True,
75+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.DAY),
76+
),
77+
PydanticDimension(
78+
name="home_state",
79+
type=DimensionType.CATEGORICAL,
80+
),
81+
PydanticDimension(
82+
name="last_profile_edit_ts",
83+
type=DimensionType.TIME,
84+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.MILLISECOND),
85+
),
86+
PydanticDimension(
87+
name="bio_added_ts",
88+
type=DimensionType.TIME,
89+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.SECOND),
90+
),
91+
PydanticDimension(
92+
name="last_login_ts",
93+
type=DimensionType.TIME,
94+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.MINUTE),
95+
),
96+
PydanticDimension(
97+
name="archived_at",
98+
type=DimensionType.TIME,
99+
type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.HOUR),
100+
),
101+
],
102+
measures=[
103+
PydanticMeasure(
104+
name="archived_users",
105+
agg=AggregationType.SUM,
106+
expr="1",
107+
create_metric=True,
108+
)
109+
],
110+
)
111+
112+
113+
def test_e2e_measure_create_metric_then_cumulative_uses_metric_input() -> None:
114+
"""End-to-end: measure create_metric=True, cumulative references created metric by name."""
115+
sm = _build_semantic_model_with_creatable_measure("sm", time_dim_name="ds")
116+
117+
metrics = [
118+
PydanticMetric(
119+
name="subdaily_cumulative_window_metric",
120+
type=MetricType.CUMULATIVE,
121+
description="m1_cumulative_1 description",
122+
type_params=PydanticMetricTypeParams(
123+
measure=PydanticMetricInputMeasure(name="archived_users"),
124+
cumulative_type_params=PydanticCumulativeTypeParams(
125+
window=PydanticMetricTimeWindow(count=3, granularity="hour"),
126+
),
127+
),
128+
),
129+
PydanticMetric(
130+
name="subdaily_cumulative_grain_to_date_metric",
131+
type=MetricType.CUMULATIVE,
132+
description="m1_cumulative_2 description",
133+
type_params=PydanticMetricTypeParams(
134+
measure=PydanticMetricInputMeasure(name="archived_users"),
135+
cumulative_type_params=PydanticCumulativeTypeParams(
136+
grain_to_date="hour",
137+
),
138+
),
139+
),
140+
PydanticMetric(
141+
name="subdaily_offset_window_metric",
142+
type=MetricType.DERIVED,
143+
description="archived_users_offset_window description",
144+
type_params=PydanticMetricTypeParams(
145+
expr="archived_users",
146+
metrics=[
147+
PydanticMetricInput(
148+
name="archived_users",
149+
offset_window=PydanticMetricTimeWindow(count=1, granularity="hour"),
150+
)
151+
],
152+
),
153+
),
154+
PydanticMetric(
155+
name="subdaily_offset_grain_to_date_metric",
156+
type=MetricType.DERIVED,
157+
description="offset grain to date metric with a sub-daily agg time dim",
158+
type_params=PydanticMetricTypeParams(
159+
expr="archived_users",
160+
metrics=[
161+
PydanticMetricInput(
162+
name="archived_users",
163+
offset_to_grain="hour",
164+
)
165+
],
166+
),
167+
),
168+
PydanticMetric(
169+
name="subdaily_join_to_time_spine_metric",
170+
type=MetricType.SIMPLE,
171+
description="simple metric with sub-daily agg time dim that joins to time spine",
172+
type_params=PydanticMetricTypeParams(
173+
measure=PydanticMetricInputMeasure(
174+
name="archived_users",
175+
join_to_timespine=True,
176+
),
177+
),
178+
),
179+
PydanticMetric(
180+
name="simple_subdaily_metric_default_day",
181+
type=MetricType.SIMPLE,
182+
description="simple metric with sub-daily agg time dim that doesn't specify default granularity",
183+
type_params=PydanticMetricTypeParams(
184+
measure=PydanticMetricInputMeasure(
185+
name="archived_users",
186+
),
187+
),
188+
),
189+
PydanticMetric(
190+
name="simple_subdaily_metric_default_hour",
191+
type=MetricType.SIMPLE,
192+
description="simple metric with sub-daily agg time dim that has an explicit default granularity",
193+
type_params=PydanticMetricTypeParams(
194+
measure=PydanticMetricInputMeasure(
195+
name="archived_users",
196+
),
197+
),
198+
time_granularity="hour",
199+
),
200+
PydanticMetric(
201+
name="archived_users_join_to_time_spine",
202+
type=MetricType.SIMPLE,
203+
description="subdaily metric joining to time spine",
204+
type_params=PydanticMetricTypeParams(
205+
measure=PydanticMetricInputMeasure(
206+
name="archived_users",
207+
join_to_timespine=True,
208+
),
209+
),
210+
),
211+
]
212+
213+
manifest = PydanticSemanticManifest(
214+
semantic_models=[sm],
215+
metrics=metrics,
216+
project_configuration=_project_config(),
217+
)
218+
219+
transformed = PydanticSemanticManifestTransformer.transform(model=manifest)
220+
221+
model_validator = SemanticManifestValidator[PydanticSemanticManifest]()
222+
model_validator.checked_validations(transformed)
223+
224+
# Expect exactly 1 new metric - the proxy simple metric created for the measure
225+
assert len(transformed.metrics) == len(metrics) + 1
226+
assert any(m for m in transformed.metrics if m.type == MetricType.SIMPLE and m.name == "archived_users")

0 commit comments

Comments
 (0)