From 32c683ce0648a7c20baf39f3273dc9c428a7b2d2 Mon Sep 17 00:00:00 2001 From: Devon Fulcher <24593113+DevonFulcher@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:56:38 -0500 Subject: [PATCH] Fix time spine validation error (#354) ### Description In my last PR, I removed an early return statement [here](https://github.com/dbt-labs/dbt-semantic-interfaces/pull/353/files#diff-23094b690ea30acfa70bbe8b29789680bc46582dfcc3c56ce1e8ce929d62781eL42). This introduced a bug when users hadn't defined a time_spine configuration. This bug wasn't released. I noticed it in my testing. ### Checklist - [x] I have read [the contributing guide](https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/CONTRIBUTING.md) and understand what's expected of me - [x] I have signed the [CLA](https://docs.getdbt.com/docs/contributor-license-agreements) - [x] This PR includes tests, or tests are not required/relevant for this PR - [x] I have run `changie new` to [create a changelog entry](https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) --- .../unreleased/Fixes-20241010-142329.yaml | 6 ++++ README.md | 2 +- .../validations/time_spines.py | 6 +++- tests/validations/test_time_spines.py | 36 +++++++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/Fixes-20241010-142329.yaml diff --git a/.changes/unreleased/Fixes-20241010-142329.yaml b/.changes/unreleased/Fixes-20241010-142329.yaml new file mode 100644 index 00000000..ba0c12ab --- /dev/null +++ b/.changes/unreleased/Fixes-20241010-142329.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: Fix time spine validation error +time: 2024-10-10T14:23:29.392029-05:00 +custom: + Author: DevonFulcher + Issue: None diff --git a/README.md b/README.md index a69004f1..7a0ee649 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ # dbt-semantic-interfaces -This repo contains the shared semantic classes, default validation, and tests designed to be used by both the dbt-core and MetricFlow projects. By centralizing these shared resources, we aim to maintain consistency and reduce code duplication across both projects. +This repo contains the shared semantic classes, default validation, and tests designed to be used by both the dbt-core and MetricFlow projects. By centralizing these shared resources, we aim to maintain consistency and reduce code duplication across both projects. ## Features - Protocols for shared semantic classes: Define the interfaces and common attributes that must be implemented by the objects in both projects. diff --git a/dbt_semantic_interfaces/validations/time_spines.py b/dbt_semantic_interfaces/validations/time_spines.py index 002affe3..9531df1d 100644 --- a/dbt_semantic_interfaces/validations/time_spines.py +++ b/dbt_semantic_interfaces/validations/time_spines.py @@ -28,10 +28,14 @@ def validate_manifest(semantic_manifest: SemanticManifestT) -> Sequence[Validati if not semantic_manifest.semantic_models: return issues + time_spines = semantic_manifest.project_configuration.time_spines + if not time_spines: + return issues + # Verify that there is only one time spine per granularity time_spines_by_granularity: Dict[TimeGranularity, List[TimeSpine]] = {} granularities_with_multiple_time_spines: Set[TimeGranularity] = set() - for time_spine in semantic_manifest.project_configuration.time_spines: + for time_spine in time_spines: granularity = time_spine.primary_column.time_granularity if granularity in time_spines_by_granularity: time_spines_by_granularity[granularity].append(time_spine) diff --git a/tests/validations/test_time_spines.py b/tests/validations/test_time_spines.py index 70beba35..20cadc88 100644 --- a/tests/validations/test_time_spines.py +++ b/tests/validations/test_time_spines.py @@ -127,6 +127,42 @@ def test_no_warning_for_legacy_time_spine() -> None: # noqa: D assert len(issues.warnings) == 0 +def test_no_time_spine_config() -> None: # noqa: D + validator = SemanticManifestValidator[PydanticSemanticManifest]() + semantic_manifest = PydanticSemanticManifest( + semantic_models=[ + semantic_model_with_guaranteed_meta( + name="sum_measure", + dimensions=[ + PydanticDimension( + name="dim", + type=DimensionType.TIME, + description="", + metadata=None, + type_params=PydanticDimensionTypeParams(time_granularity=TimeGranularity.SECOND), + ) + ], + entities=[PydanticEntity(name="entity", type=EntityType.PRIMARY)], + ), + ], + metrics=[ + PydanticMetric( + name="metric", + description=None, + type=MetricType.SIMPLE, + type_params=PydanticMetricTypeParams(measure=PydanticMetricInputMeasure(name="sum_measure")), + ), + ], + project_configuration=PydanticProjectConfiguration( + time_spine_table_configurations=[], + time_spines=[], + ), + ) + issues = validator.validate_semantic_manifest(semantic_manifest) + assert not issues.has_blocking_issues + assert len(issues.warnings) == 0 + + def test_duplicate_time_spine_granularity() -> None: # noqa: D validator = SemanticManifestValidator[PydanticSemanticManifest]() semantic_manifest = PydanticSemanticManifest(