Skip to content

Commit

Permalink
Nest query params in saved query YAML (#196)
Browse files Browse the repository at this point in the history
* Nest query params in saved query YAML

* Changelog
  • Loading branch information
courtneyholcomb authored Oct 26, 2023
1 parent 637cbb5 commit 8497151
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 91 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20231026-113940.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Nest query params for saved queries.
time: 2023-10-26T11:39:40.713149-07:00
custom:
Author: courtneyholcomb
Issue: "197"
22 changes: 17 additions & 5 deletions dbt_semantic_interfaces/implementations/saved_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,34 @@
)
from dbt_semantic_interfaces.implementations.metadata import PydanticMetadata
from dbt_semantic_interfaces.protocols import ProtocolHint
from dbt_semantic_interfaces.protocols.saved_query import SavedQuery
from dbt_semantic_interfaces.protocols.saved_query import (
SavedQuery,
SavedQueryQueryParams,
)


class PydanticSavedQuery(HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[SavedQuery]):
class PydanticSavedQueryQueryParams(HashableBaseModel, ProtocolHint[SavedQueryQueryParams]):
"""Pydantic implementation of SavedQuery."""

@override
def _implements_protocol(self) -> SavedQuery:
def _implements_protocol(self) -> SavedQueryQueryParams:
return self

name: str
metrics: List[str]
group_by: List[str] = []
where: Optional[PydanticWhereFilterIntersection] = None


class PydanticSavedQuery(HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[SavedQuery]):
"""Pydantic implementation of SavedQuery."""

@override
def _implements_protocol(self) -> SavedQuery:
return self

name: str
query_params: PydanticSavedQueryQueryParams
description: Optional[str] = None
metadata: Optional[PydanticMetadata] = None
label: Optional[str] = None
exports: Optional[List[PydanticExport]] = None
exports: List[PydanticExport] = []
Original file line number Diff line number Diff line change
Expand Up @@ -464,44 +464,57 @@
],
"type": "object"
},
"saved_query_schema": {
"$id": "saved_query_schema",
"saved_query_query_params_schema": {
"$id": "saved_query_query_params_schema",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"exports": {
"group_by": {
"items": {
"$ref": "#/definitions/export_schema"
"type": "string"
},
"type": "array"
},
"group_by": {
"metrics": {
"items": {
"type": "string"
},
"type": "array"
},
"label": {
"where": {
"$ref": "#/definitions/filter_schema"
}
},
"required": [
"metrics"
],
"type": "object"
},
"saved_query_schema": {
"$id": "saved_query_schema",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"metrics": {
"exports": {
"items": {
"type": "string"
"$ref": "#/definitions/export_schema"
},
"type": "array"
},
"label": {
"type": "string"
},
"name": {
"type": "string"
},
"where": {
"$ref": "#/definitions/filter_schema"
"query_params": {
"$ref": "#/definitions/saved_query_query_params_schema"
}
},
"required": [
"name",
"metrics"
"query_params"
],
"type": "object"
},
Expand Down
21 changes: 16 additions & 5 deletions dbt_semantic_interfaces/parsing/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,10 @@
"additionalProperties": False,
}

saved_query_schema = {
"$id": "saved_query_schema",
saved_query_query_params_schema = {
"$id": "saved_query_query_params_schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"metrics": {
"type": "array",
"items": {"type": "string"},
Expand All @@ -331,10 +329,22 @@
"items": {"type": "string"},
},
"where": {"$ref": "filter_schema"},
},
"required": ["metrics"],
"additionalProperties": False,
}

saved_query_schema = {
"$id": "saved_query_schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"query_params": {"$ref": "saved_query_query_params_schema"},
"label": {"type": "string"},
"exports": {"type": "array", "items": {"$ref": "export_schema"}},
},
"required": ["name", "metrics"],
"required": ["name", "query_params"],
"additionalProperties": False,
}

Expand Down Expand Up @@ -385,6 +395,7 @@
time_spine_table_configuration_schema["$id"]: time_spine_table_configuration_schema,
export_schema["$id"]: export_schema,
export_config_schema["$id"]: export_config_schema,
saved_query_query_params_schema["$id"]: saved_query_query_params_schema,
}

resources: List[Tuple[str, Resource]] = [(str(k), DRAFT7.create_resource(v)) for k, v in schema_store.items()]
Expand Down
30 changes: 20 additions & 10 deletions dbt_semantic_interfaces/protocols/saved_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,48 @@
from dbt_semantic_interfaces.protocols.where_filter import WhereFilterIntersection


class SavedQuery(Protocol):
"""Represents a query that the user wants to run repeatedly."""
class SavedQueryQueryParams(Protocol):
"""The parameters that will be passed into the MF query."""

@property
@abstractmethod
def metadata(self) -> Optional[Metadata]: # noqa: D
def metrics(self) -> Sequence[str]: # noqa: D
pass

@property
@abstractmethod
def name(self) -> str: # noqa: D
def group_by(self) -> Sequence[str]: # noqa: D
pass

@property
@abstractmethod
def description(self) -> Optional[str]: # noqa: D
def where(self) -> Optional[WhereFilterIntersection]:
"""Returns the intersection class containing any where filters specified in the saved query."""
pass


class SavedQuery(Protocol):
"""Represents a query that the user wants to run repeatedly."""

@property
@abstractmethod
def metadata(self) -> Optional[Metadata]: # noqa: D
pass

@property
@abstractmethod
def metrics(self) -> Sequence[str]: # noqa: D
def name(self) -> str: # noqa: D
pass

@property
@abstractmethod
def group_by(self) -> Sequence[str]: # noqa: D
def description(self) -> Optional[str]: # noqa: D
pass

@property
@abstractmethod
def where(self) -> Optional[WhereFilterIntersection]:
"""Returns the intersection class containing any where filters specified in the saved query."""
def query_params(self) -> SavedQueryQueryParams:
"""Parameters that should be passed into the MF query."""
pass

@property
Expand All @@ -48,6 +58,6 @@ def label(self) -> Optional[str]:

@property
@abstractmethod
def exports(self) -> Optional[Sequence[Export]]:
def exports(self) -> Sequence[Export]:
"""Exports that can run using this saved query."""
pass
8 changes: 4 additions & 4 deletions dbt_semantic_interfaces/validations/saved_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ 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 in saved_query.group_by:
for group_by_item in saved_query.query_params.group_by:
# TODO: Replace with more appropriate abstractions once available.
parameter_sets: FilterCallParameterSets
try:
Expand Down Expand Up @@ -83,7 +83,7 @@ def _check_group_bys(valid_group_by_element_names: Set[str], saved_query: SavedQ
@validate_safely("Validate the metrics field in a saved query.")
def _check_metrics(valid_metric_names: Set[str], saved_query: SavedQuery) -> Sequence[ValidationIssue]:
issues: List[ValidationIssue] = []
for metric_name in saved_query.metrics:
for metric_name in saved_query.query_params.metrics:
if metric_name not in valid_metric_names:
issues.append(
ValidationError(
Expand All @@ -101,9 +101,9 @@ def _check_metrics(valid_metric_names: Set[str], saved_query: SavedQuery) -> Seq
@validate_safely("Validate the where field in a saved query.")
def _check_where(saved_query: SavedQuery) -> Sequence[ValidationIssue]:
issues: List[ValidationIssue] = []
if saved_query.where is None:
if saved_query.query_params.where is None:
return issues
for where_filter in saved_query.where.where_filters:
for where_filter in saved_query.query_params.where.where_filters:
try:
where_filter.call_parameter_sets
except Exception as e:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
saved_query:
name: p0_booking
description: Booking-related metrics that are of the highest priority.
metrics:
- bookings
- instant_bookings
group_by:
- TimeDimension('metric_time', 'DAY')
- Dimension('listing__capacity_latest')
where:
- "{{ Dimension('listing__capacity_latest') }} > 3"
query_params:
metrics:
- bookings
- instant_bookings
group_by:
- TimeDimension('metric_time', 'DAY')
- Dimension('listing__capacity_latest')
where:
- "{{ Dimension('listing__capacity_latest') }} > 3"
exports:
- name: bookings
config:
Expand Down
Loading

0 comments on commit 8497151

Please sign in to comment.