Skip to content

Commit

Permalink
[CT-2879] Fix unbound variable error in `checked_agg_time_dimension_f…
Browse files Browse the repository at this point in the history
…or_measure` (#8235) (#8240)

* Fix unbound variable error in `checked_agg_time_dimension_for_measure`

* Improve assertion error message in `checked_agg_time_dimension_for_measure`

* Add changie doc for checked_agg_time_dimension_for_measure unbound variable fix

* Add unit tests for checking functionality of `checked_agg_time_dimension_for_measure`

Co-authored-by: Emily Rockman <emily.rockman@dbtlabs.com>
  • Loading branch information
QMalcolm and emmyoop authored Jul 28, 2023
1 parent 2aa3c9e commit ec50a94
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20230727-125830.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Fix unbound local variable error in `checked_agg_time_dimension_for_measure`
time: 2023-07-27T12:58:30.673803-07:00
custom:
Author: QMalcolm
Issue: "8230"
13 changes: 7 additions & 6 deletions core/dbt/contracts/graph/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1568,14 +1568,15 @@ def checked_agg_time_dimension_for_measure(
measure is not None
), f"No measure with name ({measure_reference.element_name}) in semantic_model with name ({self.name})"

if self.defaults is not None:
default_agg_time_dimesion = self.defaults.agg_time_dimension
default_agg_time_dimension = (
self.defaults.agg_time_dimension if self.defaults is not None else None
)

agg_time_dimension_name = measure.agg_time_dimension or default_agg_time_dimesion
agg_time_dimension_name = measure.agg_time_dimension or default_agg_time_dimension
assert agg_time_dimension_name is not None, (
f"Aggregation time dimension for measure {measure.name} is not set! This should either be set directly on "
f"the measure specification in the model, or else defaulted to the primary time dimension in the data "
f"source containing the measure."
f"Aggregation time dimension for measure {measure.name} on semantic model {self.name} is not set! "
"To fix this either specify a default `agg_time_dimension` for the semantic model or define an "
"`agg_time_dimension` on the measure directly."
)
return TimeDimensionReference(element_name=agg_time_dimension_name)

Expand Down
81 changes: 81 additions & 0 deletions tests/unit/test_semantic_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import pytest

from typing import List

from dbt.contracts.graph.nodes import SemanticModel
from dbt.contracts.graph.semantic_models import Dimension, Entity, Measure, Defaults
from dbt.node_types import NodeType
from dbt_semantic_interfaces.references import MeasureReference
from dbt_semantic_interfaces.type_enums import AggregationType, DimensionType, EntityType


@pytest.fixture(scope="function")
def dimensions() -> List[Dimension]:
return [Dimension(name="ds", type=DimensionType)]


@pytest.fixture(scope="function")
def entities() -> List[Entity]:
return [Entity(name="test_entity", type=EntityType.PRIMARY, expr="id")]


@pytest.fixture(scope="function")
def measures() -> List[Measure]:
return [Measure(name="test_measure", agg=AggregationType.COUNT, expr="id")]


@pytest.fixture(scope="function")
def default_semantic_model(
dimensions: List[Dimension], entities: List[Entity], measures: List[Measure]
) -> SemanticModel:
return SemanticModel(
name="test_semantic_model",
resource_type=NodeType.SemanticModel,
model="ref('test_model')",
package_name="test",
path="test_path",
original_file_path="test_fixture",
unique_id=f"{NodeType.SemanticModel}.test.test_semantic_model",
fqn=[],
defaults=Defaults(agg_time_dimension="ds"),
dimensions=dimensions,
entities=entities,
measures=measures,
node_relation=None,
)


def test_checked_agg_time_dimension_for_measure_via_defaults(
default_semantic_model: SemanticModel,
):
assert default_semantic_model.defaults.agg_time_dimension is not None
measure = default_semantic_model.measures[0]
measure.agg_time_dimension = None
default_semantic_model.checked_agg_time_dimension_for_measure(
MeasureReference(element_name=measure.name)
)


def test_checked_agg_time_dimension_for_measure_via_measure(default_semantic_model: SemanticModel):
default_semantic_model.defaults = None
measure = default_semantic_model.measures[0]
measure.agg_time_dimension = default_semantic_model.dimensions[0].name
default_semantic_model.checked_agg_time_dimension_for_measure(
MeasureReference(element_name=measure.name)
)


def test_checked_agg_time_dimension_for_measure_exception(default_semantic_model: SemanticModel):
default_semantic_model.defaults = None
measure = default_semantic_model.measures[0]
measure.agg_time_dimension = None

with pytest.raises(AssertionError) as execinfo:
default_semantic_model.checked_agg_time_dimension_for_measure(
MeasureReference(measure.name)
)

assert (
f"Aggregation time dimension for measure {measure.name} on semantic model {default_semantic_model.name}"
in str(execinfo.value)
)

0 comments on commit ec50a94

Please sign in to comment.