mirror of
https://github.com/apache/superset.git
synced 2024-09-17 19:19:38 -04:00
fix(sqla): convert prequery results to native python types (#17195)
This commit is contained in:
parent
35cbcc4643
commit
2ba046f228
@ -1391,7 +1391,7 @@ class SqlaTable(Model, BaseDatasource): # pylint: disable=too-many-public-metho
|
|||||||
if c not in metrics and c in groupby_series_columns
|
if c not in metrics and c in groupby_series_columns
|
||||||
]
|
]
|
||||||
top_groups = self._get_top_groups(
|
top_groups = self._get_top_groups(
|
||||||
result.df, dimensions, groupby_series_columns
|
result.df, dimensions, groupby_series_columns, columns_by_name
|
||||||
)
|
)
|
||||||
qry = qry.where(top_groups)
|
qry = qry.where(top_groups)
|
||||||
|
|
||||||
@ -1436,20 +1436,23 @@ class SqlaTable(Model, BaseDatasource): # pylint: disable=too-many-public-metho
|
|||||||
return ob
|
return ob
|
||||||
|
|
||||||
def _get_top_groups(
|
def _get_top_groups(
|
||||||
self, df: pd.DataFrame, dimensions: List[str], groupby_exprs: Dict[str, Any],
|
self,
|
||||||
|
df: pd.DataFrame,
|
||||||
|
dimensions: List[str],
|
||||||
|
groupby_exprs: Dict[str, Any],
|
||||||
|
columns_by_name: Dict[str, TableColumn],
|
||||||
) -> ColumnElement:
|
) -> ColumnElement:
|
||||||
column_map = {column.column_name: column for column in self.columns}
|
|
||||||
groups = []
|
groups = []
|
||||||
for _unused, row in df.iterrows():
|
for _unused, row in df.iterrows():
|
||||||
group = []
|
group = []
|
||||||
for dimension in dimensions:
|
for dimension in dimensions:
|
||||||
value = row[dimension]
|
value = utils.normalize_prequery_result_type(row[dimension])
|
||||||
|
|
||||||
# Some databases like Druid will return timestamps as strings, but
|
# Some databases like Druid will return timestamps as strings, but
|
||||||
# do not perform automatic casting when comparing these strings to
|
# do not perform automatic casting when comparing these strings to
|
||||||
# a timestamp. For cases like this we convert the value from a
|
# a timestamp. For cases like this we convert the value from a
|
||||||
# string into a timestamp.
|
# string into a timestamp.
|
||||||
if column_map[dimension].is_temporal and isinstance(value, str):
|
if columns_by_name[dimension].is_temporal and isinstance(value, str):
|
||||||
dttm = dateutil.parser.parse(value)
|
dttm = dateutil.parser.parse(value)
|
||||||
value = text(self.db_engine_spec.convert_dttm("TIMESTAMP", dttm))
|
value = text(self.db_engine_spec.convert_dttm("TIMESTAMP", dttm))
|
||||||
|
|
||||||
|
@ -1813,3 +1813,35 @@ def escape_sqla_query_binds(sql: str) -> str:
|
|||||||
sql = sql.replace(bind, bind.replace(":", "\\:"))
|
sql = sql.replace(bind, bind.replace(":", "\\:"))
|
||||||
processed_binds.add(bind)
|
processed_binds.add(bind)
|
||||||
return sql
|
return sql
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_prequery_result_type(
|
||||||
|
value: Union[str, int, float, bool, np.generic]
|
||||||
|
) -> Union[str, int, float, bool]:
|
||||||
|
"""
|
||||||
|
Convert a value that is potentially a numpy type into its equivalent Python type.
|
||||||
|
|
||||||
|
:param value: primitive datatype in either numpy or python format
|
||||||
|
:return: equivalent primitive python type
|
||||||
|
>>> normalize_prequery_result_type('abc')
|
||||||
|
'abc'
|
||||||
|
>>> normalize_prequery_result_type(True)
|
||||||
|
True
|
||||||
|
>>> normalize_prequery_result_type(123)
|
||||||
|
123
|
||||||
|
>>> normalize_prequery_result_type(np.int16(123))
|
||||||
|
123
|
||||||
|
>>> normalize_prequery_result_type(np.uint32(123))
|
||||||
|
123
|
||||||
|
>>> normalize_prequery_result_type(np.int64(123))
|
||||||
|
123
|
||||||
|
>>> normalize_prequery_result_type(123.456)
|
||||||
|
123.456
|
||||||
|
>>> normalize_prequery_result_type(np.float32(123.456))
|
||||||
|
123.45600128173828
|
||||||
|
>>> normalize_prequery_result_type(np.float64(123.456))
|
||||||
|
123.456
|
||||||
|
"""
|
||||||
|
if isinstance(value, np.generic):
|
||||||
|
return value.item()
|
||||||
|
return value
|
||||||
|
Loading…
Reference in New Issue
Block a user