Skip to content

Commit

Permalink
Backport #8646: Support labels for semantic_models, dimensions, measu…
Browse files Browse the repository at this point in the history
…res and entities (#8729)

Co-authored-by: Emily Rockman <[email protected]>
  • Loading branch information
aranke and emmyoop authored Sep 27, 2023
1 parent 5f897a0 commit 5010e87
Show file tree
Hide file tree
Showing 7 changed files with 578 additions and 53 deletions.
7 changes: 7 additions & 0 deletions .changes/unreleased/Features-20230914-074429.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Features
body: Add support for optional label in semantic_models, measures, dimensions and
entities.
time: 2023-09-14T07:44:29.828199-05:00
custom:
Author: emmyoop
Issue: "8595"
1 change: 1 addition & 0 deletions core/dbt/contracts/graph/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,7 @@ class SemanticModel(GraphNode):
model: str
node_relation: Optional[NodeRelation]
description: Optional[str] = None
label: Optional[str] = None
defaults: Optional[Defaults] = None
entities: Sequence[Entity] = field(default_factory=list)
measures: Sequence[Measure] = field(default_factory=list)
Expand Down
3 changes: 3 additions & 0 deletions core/dbt/contracts/graph/semantic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Dimension(dbtClassMixin):
name: str
type: DimensionType
description: Optional[str] = None
label: Optional[str] = None
is_partition: bool = False
type_params: Optional[DimensionTypeParams] = None
expr: Optional[str] = None
Expand Down Expand Up @@ -100,6 +101,7 @@ class Entity(dbtClassMixin):
name: str
type: EntityType
description: Optional[str] = None
label: Optional[str] = None
role: Optional[str] = None
expr: Optional[str] = None

Expand Down Expand Up @@ -136,6 +138,7 @@ class Measure(dbtClassMixin):
name: str
agg: AggregationType
description: Optional[str] = None
label: Optional[str] = None
create_metric: bool = False
expr: Optional[str] = None
agg_params: Optional[MeasureAggregationParameters] = None
Expand Down
4 changes: 4 additions & 0 deletions core/dbt/contracts/graph/unparsed.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ class UnparsedEntity(dbtClassMixin):
name: str
type: str # EntityType enum
description: Optional[str] = None
label: Optional[str] = None
role: Optional[str] = None
expr: Optional[str] = None

Expand All @@ -692,6 +693,7 @@ class UnparsedMeasure(dbtClassMixin):
name: str
agg: str # actually an enum
description: Optional[str] = None
label: Optional[str] = None
expr: Optional[Union[str, bool, int]] = None
agg_params: Optional[MeasureAggregationParameters] = None
non_additive_dimension: Optional[UnparsedNonAdditiveDimension] = None
Expand All @@ -709,6 +711,7 @@ class UnparsedDimension(dbtClassMixin):
name: str
type: str # actually an enum
description: Optional[str] = None
label: Optional[str] = None
is_partition: bool = False
type_params: Optional[UnparsedDimensionTypeParams] = None
expr: Optional[str] = None
Expand All @@ -719,6 +722,7 @@ class UnparsedSemanticModel(dbtClassMixin):
name: str
model: str # looks like "ref(...)"
description: Optional[str] = None
label: Optional[str] = None
defaults: Optional[Defaults] = None
entities: List[UnparsedEntity] = field(default_factory=list)
measures: List[UnparsedMeasure] = field(default_factory=list)
Expand Down
4 changes: 4 additions & 0 deletions core/dbt/parser/schema_yaml_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ def _get_dimensions(self, unparsed_dimensions: List[UnparsedDimension]) -> List[
name=unparsed.name,
type=DimensionType(unparsed.type),
description=unparsed.description,
label=unparsed.label,
is_partition=unparsed.is_partition,
type_params=self._get_dimension_type_params(unparsed=unparsed.type_params),
expr=unparsed.expr,
Expand All @@ -472,6 +473,7 @@ def _get_entities(self, unparsed_entities: List[UnparsedEntity]) -> List[Entity]
name=unparsed.name,
type=EntityType(unparsed.type),
description=unparsed.description,
label=unparsed.label,
role=unparsed.role,
expr=unparsed.expr,
)
Expand Down Expand Up @@ -499,6 +501,7 @@ def _get_measures(self, unparsed_measures: List[UnparsedMeasure]) -> List[Measur
name=unparsed.name,
agg=AggregationType(unparsed.agg),
description=unparsed.description,
label=unparsed.label,
expr=str(unparsed.expr) if unparsed.expr is not None else None,
agg_params=unparsed.agg_params,
non_additive_dimension=self._get_non_additive_dimension(
Expand All @@ -519,6 +522,7 @@ def parse_semantic_model(self, unparsed: UnparsedSemanticModel):

parsed = SemanticModel(
description=unparsed.description,
label=unparsed.label,
fqn=fqn,
model=unparsed.model,
name=unparsed.name,
Expand Down
246 changes: 246 additions & 0 deletions tests/functional/semantic_models/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
simple_metricflow_time_spine_sql = """
SELECT to_date('02/20/2023', 'mm/dd/yyyy') as date_day
"""

models_people_sql = """
select 1 as id, 'Drew' as first_name, 'Banin' as last_name, 'yellow' as favorite_color, true as loves_dbt, 5 as tenure, current_timestamp as created_at
union all
select 2 as id, 'Jeremy' as first_name, 'Cohen' as last_name, 'indigo' as favorite_color, true as loves_dbt, 4 as tenure, current_timestamp as created_at
union all
select 3 as id, 'Callum' as first_name, 'McCann' as last_name, 'emerald' as favorite_color, true as loves_dbt, 0 as tenure, current_timestamp as created_at
"""

groups_yml = """
version: 2
groups:
- name: some_group
owner:
email: [email protected]
- name: some_other_group
owner:
email: [email protected]
"""

models_people_metrics_yml = """
version: 2
metrics:
- name: number_of_people
label: "Number of people"
description: Total count of people
type: simple
type_params:
measure: people
meta:
my_meta: 'testing'
"""

disabled_models_people_metrics_yml = """
version: 2
metrics:
- name: number_of_people
config:
enabled: false
group: some_group
label: "Number of people"
description: Total count of people
type: simple
type_params:
measure: people
meta:
my_meta: 'testing'
"""

semantic_model_people_yml = """
version: 2
semantic_models:
- name: semantic_people
label: "Semantic People"
model: ref('people')
dimensions:
- name: favorite_color
label: "Favorite Color"
type: categorical
- name: created_at
label: "Created At"
type: TIME
type_params:
time_granularity: day
measures:
- name: years_tenure
label: "Years Tenure"
agg: SUM
expr: tenure
- name: people
label: "People"
agg: count
expr: id
entities:
- name: id
label: "Primary ID"
type: primary
defaults:
agg_time_dimension: created_at
"""

enabled_semantic_model_people_yml = """
version: 2
semantic_models:
- name: semantic_people
label: "Semantic People"
model: ref('people')
config:
enabled: true
group: some_group
dimensions:
- name: favorite_color
type: categorical
- name: created_at
type: TIME
type_params:
time_granularity: day
measures:
- name: years_tenure
agg: SUM
expr: tenure
- name: people
agg: count
expr: id
entities:
- name: id
type: primary
defaults:
agg_time_dimension: created_at
"""

disabled_semantic_model_people_yml = """
version: 2
semantic_models:
- name: semantic_people
label: "Semantic People"
model: ref('people')
config:
enabled: false
dimensions:
- name: favorite_color
type: categorical
- name: created_at
type: TIME
type_params:
time_granularity: day
measures:
- name: years_tenure
agg: SUM
expr: tenure
- name: people
agg: count
expr: id
entities:
- name: id
type: primary
defaults:
agg_time_dimension: created_at
"""

schema_yml = """models:
- name: fct_revenue
description: This is the model fct_revenue. It should be able to use doc blocks
semantic_models:
- name: revenue
description: This is the revenue semantic model. It should be able to use doc blocks
model: ref('fct_revenue')
defaults:
agg_time_dimension: ds
measures:
- name: txn_revenue
expr: revenue
agg: sum
agg_time_dimension: ds
create_metric: true
- name: sum_of_things
expr: 2
agg: sum
agg_time_dimension: ds
- name: has_revenue
expr: true
agg: sum_boolean
agg_time_dimension: ds
- name: discrete_order_value_p99
expr: order_total
agg: percentile
agg_time_dimension: ds
agg_params:
percentile: 0.99
use_discrete_percentile: True
use_approximate_percentile: False
- name: test_agg_params_optional_are_empty
expr: order_total
agg: percentile
agg_time_dimension: ds
agg_params:
percentile: 0.99
- name: test_non_additive
expr: txn_revenue
agg: sum
non_additive_dimension:
name: ds
window_choice: max
dimensions:
- name: ds
type: time
expr: created_at
type_params:
time_granularity: day
entities:
- name: user
type: foreign
expr: user_id
- name: id
type: primary
metrics:
- name: simple_metric
label: Simple Metric
type: simple
type_params:
measure: sum_of_things
"""

schema_without_semantic_model_yml = """models:
- name: fct_revenue
description: This is the model fct_revenue. It should be able to use doc blocks
"""

fct_revenue_sql = """select
1 as id,
10 as user_id,
1000 as revenue,
current_timestamp as created_at"""

metricflow_time_spine_sql = """
with days as (
{{dbt_utils.date_spine('day'
, "to_date('01/01/2000','mm/dd/yyyy')"
, "to_date('01/01/2027','mm/dd/yyyy')"
)
}}
),
final as (
select cast(date_day as date) as date_day
from days
)
select *
from final
"""
Loading

0 comments on commit 5010e87

Please sign in to comment.