From b5837416b65ffef64986606dfa764f94ac485c15 Mon Sep 17 00:00:00 2001 From: serramatutu Date: Tue, 12 Nov 2024 15:41:06 +0100 Subject: [PATCH] feat: allow groupby-only queries This commit adds support for group_by only adhoc queries with no metrics. This has a similar effect to listing dimension values, and is being added to the SDK for parity with what the ADBC and GraphQL APIs can do already. I changed the validation logic to allow for it, and I added test cases for it. --- dbtsl/api/graphql/protocol.py | 2 +- dbtsl/api/shared/query_params.py | 7 ++----- tests/query_test_cases.py | 4 ++++ tests/test_models.py | 25 ++++++++++++++----------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/dbtsl/api/graphql/protocol.py b/dbtsl/api/graphql/protocol.py index d7faa3a..4115f99 100644 --- a/dbtsl/api/graphql/protocol.py +++ b/dbtsl/api/graphql/protocol.py @@ -219,7 +219,7 @@ def get_query_request_variables(environment_id: int, params: QueryParameters) -> if isinstance(strict_params, AdhocQueryParametersStrict): return { "savedQuery": None, - "metrics": [{"name": m} for m in strict_params.metrics], + "metrics": [{"name": m} for m in strict_params.metrics] if strict_params.metrics is not None else None, "groupBy": [{"name": g} for g in strict_params.group_by] if strict_params.group_by is not None else None, **shared_vars, } diff --git a/dbtsl/api/shared/query_params.py b/dbtsl/api/shared/query_params.py index 538de28..3537715 100644 --- a/dbtsl/api/shared/query_params.py +++ b/dbtsl/api/shared/query_params.py @@ -44,7 +44,7 @@ class QueryParameters(TypedDict, total=False): class AdhocQueryParametersStrict: """The parameters of an adhoc query, strictly validated.""" - metrics: List[str] + metrics: Optional[List[str]] group_by: Optional[List[str]] limit: Optional[int] order_by: Optional[List[OrderBySpec]] @@ -125,11 +125,8 @@ def validate_query_parameters( **shared_params, ) - if "metrics" not in params or len(params["metrics"]) == 0: - raise ValueError("You need to specify at least one metric.") - return AdhocQueryParametersStrict( - metrics=params["metrics"], + metrics=params.get("metrics"), group_by=params.get("group_by"), **shared_params, ) diff --git a/tests/query_test_cases.py b/tests/query_test_cases.py index 70c4af8..7480937 100644 --- a/tests/query_test_cases.py +++ b/tests/query_test_cases.py @@ -17,6 +17,10 @@ { "metrics": ["order_total"], }, + # ad hoc query, only group by + { + "group_by": ["customer__customer_type"], + }, # ad hoc query, metric and group by { "metrics": ["order_total"], diff --git a/tests/test_models.py b/tests/test_models.py index 49c3fff..3b98320 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -178,7 +178,7 @@ def test_validate_order_by_not_found() -> None: validate_order_by(["a"], ["b"], "c") -def test_validate_query_params_adhoc_query_valid() -> None: +def test_validate_query_params_adhoc_query_valid_metrics_and_groupby() -> None: p: QueryParameters = { "metrics": ["a", "b"], "group_by": ["c", "d"], @@ -197,6 +197,18 @@ def test_validate_query_params_adhoc_query_valid() -> None: assert not r.read_cache +def test_validate_query_params_adhoc_query_valid_only_groupby() -> None: + p: QueryParameters = {"group_by": ["gb"], "limit": 1, "where": ["1=1"], "order_by": ["gb"], "read_cache": False} + r = validate_query_parameters(p) + assert isinstance(r, AdhocQueryParametersStrict) + assert r.metrics is None + assert r.group_by == ["gb"] + assert r.order_by == [OrderByGroupBy(name="gb", grain=None)] + assert r.where == ["1=1"] + assert r.limit == 1 + assert not r.read_cache + + def test_validate_query_params_saved_query_valid() -> None: p: QueryParameters = { "saved_query": "a", @@ -214,15 +226,6 @@ def test_validate_query_params_saved_query_valid() -> None: assert not r.read_cache -def test_validate_query_params_adhoc_query_no_metrics() -> None: - p: QueryParameters = { - "metrics": [], - "group_by": ["a", "b"], - } - with pytest.raises(ValueError): - validate_query_parameters(p) - - def test_validate_query_params_saved_query_group_by() -> None: p: QueryParameters = { "saved_query": "sq", @@ -239,6 +242,6 @@ def test_validate_query_params_adhoc_and_saved_query() -> None: def test_validate_query_params_no_query() -> None: - p: QueryParameters = {"group_by": ["gb"], "limit": 1, "where": ["1=1"], "order_by": ["a"], "read_cache": False} + p: QueryParameters = {"limit": 1, "where": ["1=1"], "order_by": ["a"], "read_cache": False} with pytest.raises(ValueError): validate_query_parameters(p)