Skip to content

Commit

Permalink
Change format of the group_bys in saved queries.
Browse files Browse the repository at this point in the history
  • Loading branch information
plypaul committed Sep 16, 2023
1 parent d45a108 commit 5c3593c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 12 deletions.
42 changes: 36 additions & 6 deletions dbt_semantic_interfaces/validations/saved_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import traceback
from typing import Generic, List, Sequence, Set

from dbt_semantic_interfaces.naming.dundered import DunderedNameFormatter
from dbt_semantic_interfaces.call_parameter_sets import FilterCallParameterSets
from dbt_semantic_interfaces.implementations.filters.where_filter import (
PydanticWhereFilter,
)
from dbt_semantic_interfaces.naming.keywords import METRIC_TIME_ELEMENT_NAME
from dbt_semantic_interfaces.protocols import SemanticManifestT
from dbt_semantic_interfaces.protocols.saved_query import SavedQuery
Expand Down Expand Up @@ -35,16 +38,43 @@ class SavedQueryRule(SemanticManifestValidationRule[SemanticManifestT], Generic[
def _check_group_bys(valid_group_by_element_names: Set[str], saved_query: SavedQuery) -> Sequence[ValidationIssue]:
issues: List[ValidationIssue] = []

for group_by_item_name in saved_query.group_bys:
structured_name = DunderedNameFormatter.parse_name(group_by_item_name)
if structured_name.element_name not in valid_group_by_element_names:
for group_by_item in saved_query.group_bys:
# TODO: Replace with more appropriate abstractions once available.
where_filter = PydanticWhereFilter(where_sql_template="{{" + group_by_item + "}}")
parameter_sets: FilterCallParameterSets
try:
parameter_sets = where_filter.call_parameter_sets
except Exception as e:
issues.append(
generate_exception_issue(
what_was_being_done=f"trying to parse a group-by in saved query `{saved_query.name}`",
e=e,
context=SavedQueryContext(
file_context=FileContext.from_metadata(metadata=saved_query.metadata),
element_type=SavedQueryElementType.WHERE,
element_value=where_filter.where_sql_template,
),
extras={
"traceback": "".join(traceback.format_tb(e.__traceback__)),
},
)
)
continue

element_names_in_group_by = (
[x.entity_reference.element_name for x in parameter_sets.entity_call_parameter_sets]
+ [x.dimension_reference.element_name for x in parameter_sets.dimension_call_parameter_sets]
+ [x.time_dimension_reference.element_name for x in parameter_sets.time_dimension_call_parameter_sets]
)

if len(element_names_in_group_by) != 1 or element_names_in_group_by[0] not in valid_group_by_element_names:
issues.append(
ValidationError(
message=f"`{group_by_item_name}` is not a valid group-by name.",
message=f"`{group_by_item}` is not a valid group-by name.",
context=SavedQueryContext(
file_context=FileContext.from_metadata(metadata=saved_query.metadata),
element_type=SavedQueryElementType.GROUP_BY,
element_value=group_by_item_name,
element_value=group_by_item,
),
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ saved_query:
- bookings
- instant_bookings
group_bys:
- metric_time__day
- listing__capacity_latest
- TimeDimension('metric_time', 'DAY')
- Dimension('listing__capacity_latest')
where:
- "{{ Dimension('listing__capacity_latest') }} > 3"
30 changes: 26 additions & 4 deletions tests/validations/test_saved_query.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import copy
import logging


from dbt_semantic_interfaces.implementations.filters.where_filter import (
PydanticWhereFilter,
)
Expand Down Expand Up @@ -43,7 +44,7 @@ def test_invalid_metric_in_saved_query( # noqa: D
name="Example Saved Query",
description="Example description.",
metrics=["invalid_metric"],
group_bys=["booking__is_instant"],
group_bys=["Dimension('booking__is_instant')"],
where=[PydanticWhereFilter(where_sql_template="{{ Dimension('booking__is_instant') }}")],
),
]
Expand All @@ -63,7 +64,7 @@ def test_invalid_where_in_saved_query( # noqa: D
name="Example Saved Query",
description="Example description.",
metrics=["bookings"],
group_bys=["booking__is_instant"],
group_bys=["Dimension('booking__is_instant')"],
where=[PydanticWhereFilter(where_sql_template="{{ invalid_jinja }}")],
),
]
Expand All @@ -75,7 +76,7 @@ def test_invalid_where_in_saved_query( # noqa: D
)


def test_invalid_group_by_in_saved_query( # noqa: D
def test_invalid_group_by_element_in_saved_query( # noqa: D
simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest,
) -> None:
manifest = copy.deepcopy(simple_semantic_manifest__with_primary_transforms)
Expand All @@ -84,7 +85,7 @@ def test_invalid_group_by_in_saved_query( # noqa: D
name="Example Saved Query",
description="Example description.",
metrics=["bookings"],
group_bys=["invalid_dimension"],
group_bys=["Dimension('booking__invalid_dimension')"],
where=[PydanticWhereFilter(where_sql_template="{{ Dimension('booking__is_instant') }}")],
),
]
Expand All @@ -94,3 +95,24 @@ def test_invalid_group_by_in_saved_query( # noqa: D
manifest_validator.validate_semantic_manifest(manifest),
"is not a valid group-by name.",
)


def test_invalid_group_by_format_in_saved_query( # noqa: D
simple_semantic_manifest__with_primary_transforms: PydanticSemanticManifest,
) -> None:
manifest = copy.deepcopy(simple_semantic_manifest__with_primary_transforms)
manifest.saved_queries = [
PydanticSavedQuery(
name="Example Saved Query",
description="Example description.",
metrics=["bookings"],
group_bys=["invalid_format"],
where=[PydanticWhereFilter(where_sql_template="{{ Dimension('booking__is_instant') }}")],
),
]

manifest_validator = SemanticManifestValidator[PydanticSemanticManifest]([SavedQueryRule()])
check_only_one_error_with_message(
manifest_validator.validate_semantic_manifest(manifest),
"An error occurred while trying to parse a group-by in saved query",
)

0 comments on commit 5c3593c

Please sign in to comment.