-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Unskip and rename test_expression_metric #8578
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
Changes from 12 commits
1ac2f04
b84b575
a92e5aa
c8389f9
8f0c5c6
4e062cb
4dfe539
4a11c9f
41c8ad0
b476f28
84c5091
b073cff
711ca98
70091df
da99e59
f80b4e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| kind: Fixes | ||
| body: Update metric helper functions to work with new semantic layer metrics | ||
| time: 2023-09-06T12:02:12.156534-07:00 | ||
| custom: | ||
| Author: QMalcolm | ||
| Issue: "8134" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,11 @@ | ||
| from dbt.node_types import NodeType | ||
| from dbt.contracts.graph.manifest import Manifest, Metric | ||
| from dbt_semantic_interfaces.type_enums import MetricType | ||
|
|
||
| from typing import Dict, Iterator, List | ||
|
|
||
|
|
||
| DERIVED_METRICS = [MetricType.DERIVED, MetricType.RATIO] | ||
| BASE_METRICS = [MetricType.SIMPLE, MetricType.CUMULATIVE] | ||
|
|
||
|
|
||
| class MetricReference(object): | ||
|
|
@@ -17,7 +24,7 @@ class ResolvedMetricReference(MetricReference): | |
| for working with metrics (ie. __str__ and templating functions) | ||
| """ | ||
|
|
||
| def __init__(self, node, manifest, Relation): | ||
| def __init__(self, node: Metric, manifest: Manifest, Relation=None): | ||
| super().__init__(node.name, node.package_name) | ||
| self.node = node | ||
| self.manifest = manifest | ||
|
|
@@ -30,63 +37,62 @@ def __str__(self): | |
| return f"{self.node.name}" | ||
|
|
||
| @classmethod | ||
| def parent_metrics(cls, metric_node, manifest): | ||
| def parent_metrics(cls, metric_node: Metric, manifest: Manifest) -> Iterator[Metric]: | ||
| """For a given metric, yeilds all upstream metrics.""" | ||
| yield metric_node | ||
|
|
||
| for parent_unique_id in metric_node.depends_on.nodes: | ||
| node = manifest.metrics.get(parent_unique_id) | ||
| if node and node.resource_type == NodeType.Metric: | ||
| yield from cls.parent_metrics(node, manifest) | ||
| metric = manifest.metrics.get(parent_unique_id) | ||
| if metric is not None: | ||
|
||
| yield from cls.parent_metrics(metric, manifest) | ||
|
|
||
| @classmethod | ||
| def parent_metrics_names(cls, metric_node, manifest): | ||
| yield metric_node.name | ||
|
|
||
| for parent_unique_id in metric_node.depends_on.nodes: | ||
| node = manifest.metrics.get(parent_unique_id) | ||
| if node and node.resource_type == NodeType.Metric: | ||
| yield from cls.parent_metrics_names(node, manifest) | ||
| def parent_metrics_names(cls, metric_node: Metric, manifest: Manifest) -> Iterator[str]: | ||
| """For a given metric, yeilds all upstream metric names""" | ||
| for metric in cls.parent_metrics(metric_node, manifest): | ||
| yield metric.name | ||
|
|
||
| @classmethod | ||
| def reverse_dag_parsing(cls, metric_node, manifest, metric_depth_count): | ||
| if metric_node.calculation_method == "derived": | ||
| def reverse_dag_parsing( | ||
| cls, metric_node: Metric, manifest: Manifest, metric_depth_count: int | ||
| ) -> Iterator[Dict[str, int]]: | ||
| """For the given metric, yeilds dictionaries having {<metric_name>: <depth_from_initial_metric} of upstream derived metrics. | ||
|
|
||
| This function is intended as a helper function for other metric helper functions. | ||
| """ | ||
| if metric_node.type in DERIVED_METRICS: | ||
| yield {metric_node.name: metric_depth_count} | ||
| metric_depth_count = metric_depth_count + 1 | ||
|
|
||
| for parent_unique_id in metric_node.depends_on.nodes: | ||
| node = manifest.metrics.get(parent_unique_id) | ||
| if ( | ||
| node | ||
| and node.resource_type == NodeType.Metric | ||
| and node.calculation_method == "derived" | ||
| ): | ||
| yield from cls.reverse_dag_parsing(node, manifest, metric_depth_count) | ||
| for parent_unique_id in metric_node.depends_on.nodes: | ||
| metric = manifest.metrics.get(parent_unique_id) | ||
| if metric is not None: | ||
| yield from cls.reverse_dag_parsing(metric, manifest, metric_depth_count + 1) | ||
|
|
||
| def full_metric_dependency(self): | ||
| """Returns a unique list of all upstream metric names.""" | ||
| to_return = list(set(self.parent_metrics_names(self.node, self.manifest))) | ||
| return to_return | ||
|
|
||
| def base_metric_dependency(self): | ||
| def base_metric_dependency(self) -> List[str]: | ||
| """Returns a unique list of names for all upstream non-derived metrics.""" | ||
| in_scope_metrics = list(self.parent_metrics(self.node, self.manifest)) | ||
| base_metrics = { | ||
| metric.name for metric in in_scope_metrics if metric.type not in DERIVED_METRICS | ||
| } | ||
|
|
||
| to_return = [] | ||
| for metric in in_scope_metrics: | ||
| if metric.calculation_method != "derived" and metric.name not in to_return: | ||
| to_return.append(metric.name) | ||
|
|
||
| return to_return | ||
| return list(base_metrics) | ||
|
|
||
| def derived_metric_dependency(self): | ||
| def derived_metric_dependency(self) -> List[str]: | ||
| """Returns a unique list of names for all upstream derived metrics.""" | ||
| in_scope_metrics = list(self.parent_metrics(self.node, self.manifest)) | ||
| derived_metrics = { | ||
| metric.name for metric in in_scope_metrics if metric.type in DERIVED_METRICS | ||
| } | ||
|
|
||
| to_return = [] | ||
| for metric in in_scope_metrics: | ||
| if metric.calculation_method == "derived" and metric.name not in to_return: | ||
| to_return.append(metric.name) | ||
|
|
||
| return to_return | ||
| return list(derived_metrics) | ||
|
|
||
| def derived_metric_dependency_depth(self): | ||
| def derived_metric_dependency_depth(self) -> List[Dict[str, int]]: | ||
| """Returns a list of {<metric_name>: <depth_from_initial_metric>} for all upstream metrics.""" | ||
| metric_depth_count = 1 | ||
| to_return = list(self.reverse_dag_parsing(self.node, self.manifest, metric_depth_count)) | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.