From bf0d0b89e52aa3e3bf20b0e01b5d693523fcf2f3 Mon Sep 17 00:00:00 2001 From: Lucas Valente Date: Mon, 19 Aug 2024 14:01:09 -0300 Subject: [PATCH] feat: add extra fields to `SavedQuery` (#39) Thid commit adds `Exports` and `QueryParams` to the fields of a saved query. This makes querying for them more useful than just returning a name, description and label. To make this work, I had to add an extra check in the base `GraphQLFragmentMixin` class because it didn't handle `Optional` field well. --- .../unreleased/Features-20240819-130313.yaml | 3 + .../unreleased/Features-20240819-130327.yaml | 3 + dbtsl/models/__init__.py | 22 ++++++- dbtsl/models/base.py | 4 +- dbtsl/models/dimension.py | 2 +- dbtsl/models/metric.py | 2 +- dbtsl/models/saved_query.py | 66 ++++++++++++++++++- dbtsl/models/{time_granularity.py => time.py} | 11 ++++ 8 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 .changes/unreleased/Features-20240819-130313.yaml create mode 100644 .changes/unreleased/Features-20240819-130327.yaml rename dbtsl/models/{time_granularity.py => time.py} (67%) diff --git a/.changes/unreleased/Features-20240819-130313.yaml b/.changes/unreleased/Features-20240819-130313.yaml new file mode 100644 index 0000000..188cd04 --- /dev/null +++ b/.changes/unreleased/Features-20240819-130313.yaml @@ -0,0 +1,3 @@ +kind: Features +body: Add `Export` list to `SavedQuery` +time: 2024-08-19T13:03:13.553574+02:00 diff --git a/.changes/unreleased/Features-20240819-130327.yaml b/.changes/unreleased/Features-20240819-130327.yaml new file mode 100644 index 0000000..cdade9d --- /dev/null +++ b/.changes/unreleased/Features-20240819-130327.yaml @@ -0,0 +1,3 @@ +kind: Features +body: Add `SavedQueryQueryParam` list to `SavedQuery` +time: 2024-08-19T13:03:27.820242+02:00 diff --git a/dbtsl/models/__init__.py b/dbtsl/models/__init__.py index 4453ec6..7884bb2 100644 --- a/dbtsl/models/__init__.py +++ b/dbtsl/models/__init__.py @@ -10,8 +10,17 @@ from .measure import AggregationType, Measure from .metric import Metric, MetricType from .query import QueryResult -from .saved_query import SavedQuery -from .time_granularity import TimeGranularity +from .saved_query import ( + Export, + ExportConfig, + ExportDestinationType, + SavedQuery, + SavedQueryGroupByParam, + SavedQueryMetricParam, + SavedQueryQueryParams, + SavedQueryWhereParam, +) +from .time import DatePart, TimeGranularity # Only importing this so it registers aliases _ = QueryResult @@ -20,13 +29,22 @@ __all__ = [ "AggregationType", + "DatePart", "Dimension", "DimensionType", "Entity", "EntityType", + "Export", + "ExportConfig", + "ExportDestinationType", "Measure", "Metric", "MetricType", "SavedQuery", + "SavedQuery", + "SavedQueryGroupByParam", + "SavedQueryMetricParam", + "SavedQueryQueryParams", + "SavedQueryWhereParam", "TimeGranularity", ] diff --git a/dbtsl/models/base.py b/dbtsl/models/base.py index bc08f15..ac044a3 100644 --- a/dbtsl/models/base.py +++ b/dbtsl/models/base.py @@ -66,7 +66,9 @@ def _get_fragments_for_field(type: Union[Type[Any], str], field_name: str) -> Un if inspect.isclass(type) and issubclass(type, GraphQLFragmentMixin): return type.gql_fragments() - if get_type_origin(type) is list: + type_origin = get_type_origin(type) + # Optional = Union[X, None] + if type_origin is list or type_origin is Union: inner_type = get_type_args(type)[0] return GraphQLFragmentMixin._get_fragments_for_field(inner_type, field_name) diff --git a/dbtsl/models/dimension.py b/dbtsl/models/dimension.py index 898ce7b..05e44fa 100644 --- a/dbtsl/models/dimension.py +++ b/dbtsl/models/dimension.py @@ -3,7 +3,7 @@ from typing import List, Optional from dbtsl.models.base import BaseModel, GraphQLFragmentMixin -from dbtsl.models.time_granularity import TimeGranularity +from dbtsl.models.time import TimeGranularity class DimensionType(str, Enum): diff --git a/dbtsl/models/metric.py b/dbtsl/models/metric.py index 6ce2035..034d4df 100644 --- a/dbtsl/models/metric.py +++ b/dbtsl/models/metric.py @@ -6,7 +6,7 @@ from dbtsl.models.dimension import Dimension from dbtsl.models.entity import Entity from dbtsl.models.measure import Measure -from dbtsl.models.time_granularity import TimeGranularity +from dbtsl.models.time import TimeGranularity class MetricType(str, Enum): diff --git a/dbtsl/models/saved_query.py b/dbtsl/models/saved_query.py index 41e390e..ce0068d 100644 --- a/dbtsl/models/saved_query.py +++ b/dbtsl/models/saved_query.py @@ -1,7 +1,69 @@ from dataclasses import dataclass -from typing import Optional +from enum import Enum +from typing import List, Optional from dbtsl.models.base import BaseModel, GraphQLFragmentMixin +from dbtsl.models.time import DatePart, TimeGranularity + + +class ExportDestinationType(str, Enum): + """All kinds of export destinations.""" + + TABLE = "TABLE" + VIEW = "VIEW" + + +@dataclass(frozen=True) +class ExportConfig(BaseModel, GraphQLFragmentMixin): + """A saved query export config.""" + + alias: Optional[str] + schema: Optional[str] + export_as: ExportDestinationType + + +@dataclass(frozen=True) +class Export(BaseModel, GraphQLFragmentMixin): + """A saved query export.""" + + name: str + config: ExportConfig + + +@dataclass(frozen=True) +class SavedQueryMetricParam(BaseModel, GraphQLFragmentMixin): + """The metric param of a saved query.""" + + name: str + + +@dataclass(frozen=True) +class SavedQueryGroupByParam(BaseModel, GraphQLFragmentMixin): + """The groupBy param of a saved query.""" + + name: str + grain: Optional[TimeGranularity] + date_part: Optional[DatePart] + + +@dataclass(frozen=True) +class SavedQueryWhereParam(BaseModel, GraphQLFragmentMixin): + """The where param of a saved query.""" + + @classmethod + def gql_model_name(cls) -> str: # noqa: D102 + return "WhereFilter" + + where_sql_template: str + + +@dataclass(frozen=True) +class SavedQueryQueryParams(BaseModel, GraphQLFragmentMixin): + """The parameters of a saved query.""" + + metrics: List[SavedQueryMetricParam] + group_by: List[SavedQueryGroupByParam] + where: Optional[SavedQueryWhereParam] @dataclass(frozen=True) @@ -11,3 +73,5 @@ class SavedQuery(BaseModel, GraphQLFragmentMixin): name: str description: Optional[str] label: Optional[str] + query_params: SavedQueryQueryParams + exports: List[Export] diff --git a/dbtsl/models/time_granularity.py b/dbtsl/models/time.py similarity index 67% rename from dbtsl/models/time_granularity.py rename to dbtsl/models/time.py index 3891083..81631de 100644 --- a/dbtsl/models/time_granularity.py +++ b/dbtsl/models/time.py @@ -15,3 +15,14 @@ class TimeGranularity(str, Enum): MONTH = "MONTH" QUARTER = "QUARTER" YEAR = "YEAR" + + +class DatePart(str, Enum): + """Date part.""" + + DOY = "DOY" + DOW = "DOW" + DAY = "DAY" + MONTH = "MONTH" + QUARTER = "QUARTER" + YEAR = "YEAR"