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

Backport #8646: Support labels for semantic_models, dimensions, measures and entities #8729

Merged
merged 1 commit into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading