Skip to content

Commit

Permalink
Begin checking saved query names for validity and uniqueness
Browse files Browse the repository at this point in the history
  • Loading branch information
QMalcolm committed Oct 25, 2023
1 parent 2d80dc9 commit dc364f2
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20231023-102225.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Begin validating `SavedQuery` names
time: 2023-10-23T10:22:25.686081-07:00
custom:
Author: QMalcolm
Issue: "180"
23 changes: 22 additions & 1 deletion dbt_semantic_interfaces/validations/unique_valid_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
from dbt_semantic_interfaces.protocols import (
Metric,
SavedQuery,
SemanticManifest,
SemanticManifestT,
SemanticModel,
Expand All @@ -28,6 +29,7 @@
ValidationContext,
ValidationError,
ValidationIssue,
ValidationIssueContext,
validate_safely,
)

Expand Down Expand Up @@ -172,7 +174,9 @@ def _validate_semantic_model_elements(semantic_model: SemanticModel) -> List[Val
@validate_safely(whats_being_done="checking top level elements of a specific type have unique and valid names")
def _validate_top_level_objects_of_type(
object_context_tuples: Union[
List[Tuple[SemanticModel, SemanticModelContext]], List[Tuple[Metric, MetricContext]]
List[Tuple[SemanticModel, SemanticModelContext]],
List[Tuple[Metric, MetricContext]],
List[Tuple[SavedQuery, ValidationIssueContext]],
],
object_type: str,
) -> List[ValidationIssue]:
Expand Down Expand Up @@ -232,6 +236,23 @@ def _validate_top_level_objects(semantic_manifest: SemanticManifest) -> List[Val
]
issues.extend(UniqueAndValidNameRule._validate_top_level_objects_of_type(metric_context_tuples, "metric"))

if semantic_manifest.saved_queries:
# TODO: We should clean up this pattern of precompiling object contexts
saved_query_context_tuples = [
(
saved_query,
ValidationIssueContext(
file_context=FileContext.from_metadata(metadata=saved_query.metadata),
object_type="saved query",
object_name=saved_query.name,
),
)
for saved_query in semantic_manifest.saved_queries
]
issues.extend(
UniqueAndValidNameRule._validate_top_level_objects_of_type(saved_query_context_tuples, "saved query")
)

return issues

@staticmethod
Expand Down
1 change: 1 addition & 0 deletions dbt_semantic_interfaces/validations/validator_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ def context_str(self) -> str:
SemanticModelContext,
SemanticModelElementContext,
SavedQueryContext,
ValidationIssueContext,
]


Expand Down
38 changes: 38 additions & 0 deletions tests/validations/test_unique_valid_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
Top level elements include
- Semantic Models
- Metrics
- Saved Queries
For each top level element type we test for
- Name validity checking
Expand Down Expand Up @@ -116,6 +117,43 @@ def test_top_level_metric_can_have_same_name_as_any_other_top_level_item( # noq
)


def test_saved_query_name_validity( # noqa: D
simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest,
):
validator = SemanticManifestValidator[PydanticSemanticManifest](
[UniqueAndValidNameRule[PydanticSemanticManifest]()]
)

# Shouldn't raise an exception
validator.checked_validations(simple_semantic_manifest__with_primary_transforms)

# Should raise an exception
copied_manifest = deepcopy(simple_semantic_manifest__with_primary_transforms)
saved_query = copied_manifest.saved_queries[0]
saved_query.name = f"@{saved_query.name}"
with pytest.raises(
SemanticManifestValidationException,
match=rf"Invalid name `{saved_query.name}",
):
validator.checked_validations(copied_manifest)


def test_duplicate_saved_query_name( # noqa: D
simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest,
) -> None:
manifest = deepcopy(simple_semantic_manifest__with_primary_transforms)
duplicated_saved_query = manifest.saved_queries[0]
manifest.saved_queries.append(duplicated_saved_query)
with pytest.raises(
SemanticManifestValidationException,
match=rf"Can't use name `{duplicated_saved_query.name}` for a saved query when it was already used for "
"another saved query",
):
SemanticManifestValidator[PydanticSemanticManifest](
[UniqueAndValidNameRule[PydanticSemanticManifest]()]
).checked_validations(manifest)


"""
Semantic Model Element Tests
There are three types of semantic model elements
Expand Down

0 comments on commit dc364f2

Please sign in to comment.