mirror of
https://github.com/apache/superset.git
synced 2026-04-18 07:35:09 +00:00
fix: Add deprecated fields to QueryObject schema (#9579)
* fix: Add deprecated fields to QueryObject schema * linting
This commit is contained in:
@@ -393,6 +393,19 @@ class ChartDataExtrasSchema(Schema):
|
||||
enum=["today", "now"],
|
||||
required=False,
|
||||
)
|
||||
where = fields.String(
|
||||
description="WHERE clause to be added to queries using AND operator.",
|
||||
required=False,
|
||||
)
|
||||
having = fields.String(
|
||||
description="HAVING clause to be added to aggregate queries using "
|
||||
"AND operator.",
|
||||
required=False,
|
||||
)
|
||||
having_druid = fields.String(
|
||||
description="HAVING filters to be added to legacy Druid datasource queries.",
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
||||
class ChartDataQueryObjectSchema(Schema):
|
||||
@@ -484,6 +497,27 @@ class ChartDataQueryObjectSchema(Schema):
|
||||
required=False,
|
||||
example=[["my_col_1", False], ["my_col_2", True]],
|
||||
)
|
||||
where = fields.String(
|
||||
description="WHERE clause to be added to queries using AND operator."
|
||||
"This field is deprecated, and should be passed to `extras`.",
|
||||
required=False,
|
||||
deprecated=True,
|
||||
)
|
||||
having = fields.String(
|
||||
description="HAVING clause to be added to aggregate queries using "
|
||||
"AND operator. This field is deprecated, and should be passed "
|
||||
"to `extras`.",
|
||||
required=False,
|
||||
deprecated=True,
|
||||
)
|
||||
having_filters = fields.List(
|
||||
fields.Dict(),
|
||||
description="HAVING filters to be added to legacy Druid datasource queries. "
|
||||
"This field is deprecated, and should be passed to `extras` "
|
||||
"as `filters_druid`.",
|
||||
required=False,
|
||||
deprecated=True,
|
||||
)
|
||||
|
||||
|
||||
class ChartDataDatasourceSchema(Schema):
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import hashlib
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from typing import Any, Dict, List, NamedTuple, Optional, Union
|
||||
|
||||
import simplejson as json
|
||||
from flask_babel import gettext as _
|
||||
@@ -35,6 +35,18 @@ logger = logging.getLogger(__name__)
|
||||
# https://github.com/python/mypy/issues/5288
|
||||
|
||||
|
||||
class DeprecatedExtrasField(NamedTuple):
|
||||
name: str
|
||||
extras_name: str
|
||||
|
||||
|
||||
DEPRECATED_EXTRAS_FIELDS = (
|
||||
DeprecatedExtrasField(name="where", extras_name="where"),
|
||||
DeprecatedExtrasField(name="having", extras_name="having"),
|
||||
DeprecatedExtrasField(name="having_filters", extras_name="having_druid"),
|
||||
)
|
||||
|
||||
|
||||
class QueryObject:
|
||||
"""
|
||||
The query object's schema matches the interfaces of DB connectors like sqla
|
||||
@@ -75,6 +87,7 @@ class QueryObject:
|
||||
columns: Optional[List[str]] = None,
|
||||
orderby: Optional[List[List]] = None,
|
||||
post_processing: Optional[List[Dict[str, Any]]] = None,
|
||||
**kwargs: Any,
|
||||
):
|
||||
extras = extras or {}
|
||||
is_sip_38 = is_feature_enabled("SIP_38_VIZ_REARCHITECTURE")
|
||||
@@ -124,6 +137,17 @@ class QueryObject:
|
||||
|
||||
self.orderby = orderby or []
|
||||
|
||||
# move deprecated fields to extras
|
||||
for field in DEPRECATED_EXTRAS_FIELDS:
|
||||
if field.name in kwargs:
|
||||
logger.warning(
|
||||
f"The field `{field.name} is deprecated, and should be "
|
||||
f"passed to `extras` via the `{field.extras_name}` property"
|
||||
)
|
||||
value = kwargs[field.name]
|
||||
if value:
|
||||
self.extras[field.extras_name] = value
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
query_object_dict = {
|
||||
"granularity": self.granularity,
|
||||
|
||||
@@ -24,7 +24,7 @@ from copy import deepcopy
|
||||
from datetime import datetime, timedelta
|
||||
from distutils.version import LooseVersion
|
||||
from multiprocessing.pool import ThreadPool
|
||||
from typing import cast, Dict, Iterable, List, Optional, Set, Tuple, Union
|
||||
from typing import Any, cast, Dict, Iterable, List, Optional, Set, Tuple, Union
|
||||
|
||||
import pandas as pd
|
||||
import sqlalchemy as sa
|
||||
@@ -1639,7 +1639,7 @@ class DruidDatasource(Model, BaseDatasource):
|
||||
|
||||
return cond
|
||||
|
||||
def get_having_filters(self, raw_filters: List[Dict]) -> "Having":
|
||||
def get_having_filters(self, raw_filters: List[Dict[str, Any]]) -> "Having":
|
||||
filters = None
|
||||
reversed_op_map = {
|
||||
FilterOperationType.NOT_EQUALS.value: FilterOperationType.EQUALS.value,
|
||||
|
||||
@@ -76,11 +76,21 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
|
||||
"datasource": {"id": slc.datasource_id, "type": slc.datasource_type},
|
||||
"queries": [
|
||||
{
|
||||
"extras": {"where": ""},
|
||||
"granularity": "ds",
|
||||
"groupby": ["name"],
|
||||
"is_timeseries": False,
|
||||
"metrics": [{"label": "sum__num"}],
|
||||
"filters": [],
|
||||
"order_desc": True,
|
||||
"orderby": [],
|
||||
"row_limit": 100,
|
||||
"time_range": "100 years ago : now",
|
||||
"timeseries_limit": 0,
|
||||
"timeseries_limit_metric": None,
|
||||
"filters": [{"col": "gender", "op": "==", "val": "boy"}],
|
||||
"having": "",
|
||||
"having_filters": [],
|
||||
"where": "",
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -660,8 +670,7 @@ class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
|
||||
self.assertEqual(data["result"][0]["rowcount"], 100)
|
||||
|
||||
def test_invalid_chart_data(self):
|
||||
"""
|
||||
Query API: Test chart data query
|
||||
"""Query API: Test chart data query with invalid schema
|
||||
"""
|
||||
self.login(username="admin")
|
||||
query_context = self._get_query_context()
|
||||
|
||||
Reference in New Issue
Block a user