mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
fix: Apply normalization to all dttm columns (#25147)
(cherry picked from commit 58fcd292a9)
This commit is contained in:
committed by
Michael S. Molina
parent
8b66603566
commit
dd769eb7a0
@@ -16,17 +16,24 @@
|
||||
# under the License.
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from superset.common.chart_data import ChartDataResultType
|
||||
from superset.common.query_object import QueryObject
|
||||
from superset.common.utils.time_range_utils import get_since_until_from_time_range
|
||||
from superset.utils.core import apply_max_row_limit, DatasourceDict, DatasourceType
|
||||
from superset.utils.core import (
|
||||
apply_max_row_limit,
|
||||
DatasourceDict,
|
||||
DatasourceType,
|
||||
FilterOperator,
|
||||
QueryObjectFilterClause,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from superset.connectors.base.models import BaseDatasource
|
||||
from superset.connectors.base.models import BaseColumn, BaseDatasource
|
||||
from superset.daos.datasource import DatasourceDAO
|
||||
|
||||
|
||||
@@ -66,6 +73,10 @@ class QueryObjectFactory: # pylint: disable=too-few-public-methods
|
||||
)
|
||||
kwargs["from_dttm"] = from_dttm
|
||||
kwargs["to_dttm"] = to_dttm
|
||||
if datasource_model_instance and kwargs.get("filters", []):
|
||||
kwargs["filters"] = self._process_filters(
|
||||
datasource_model_instance, kwargs["filters"]
|
||||
)
|
||||
return QueryObject(
|
||||
datasource=datasource_model_instance,
|
||||
extras=extras,
|
||||
@@ -102,3 +113,55 @@ class QueryObjectFactory: # pylint: disable=too-few-public-methods
|
||||
# light version of the view.utils.core
|
||||
# import view.utils require application context
|
||||
# Todo: move it and the view.utils.core to utils package
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def _process_filters(
|
||||
self, datasource: BaseDatasource, query_filters: list[QueryObjectFilterClause]
|
||||
) -> list[QueryObjectFilterClause]:
|
||||
def get_dttm_filter_value(
|
||||
value: Any, col: BaseColumn, date_format: str
|
||||
) -> int | str:
|
||||
if not isinstance(value, int):
|
||||
return value
|
||||
if date_format in {"epoch_ms", "epoch_s"}:
|
||||
if date_format == "epoch_s":
|
||||
value = str(value)
|
||||
else:
|
||||
value = str(value * 1000)
|
||||
else:
|
||||
dttm = datetime.utcfromtimestamp(value / 1000)
|
||||
value = dttm.strftime(date_format)
|
||||
|
||||
if col.type in col.num_types:
|
||||
value = int(value)
|
||||
return value
|
||||
|
||||
for query_filter in query_filters:
|
||||
if query_filter.get("op") == FilterOperator.TEMPORAL_RANGE:
|
||||
continue
|
||||
filter_col = query_filter.get("col")
|
||||
if not isinstance(filter_col, str):
|
||||
continue
|
||||
column = datasource.get_column(filter_col)
|
||||
if not column:
|
||||
continue
|
||||
filter_value = query_filter.get("val")
|
||||
|
||||
date_format = column.python_date_format
|
||||
if not date_format and datasource.db_extra:
|
||||
date_format = datasource.db_extra.get(
|
||||
"python_date_format_by_column_name", {}
|
||||
).get(column.column_name)
|
||||
|
||||
if column.is_dttm and date_format:
|
||||
if isinstance(filter_value, list):
|
||||
query_filter["val"] = [
|
||||
get_dttm_filter_value(value, column, date_format)
|
||||
for value in filter_value
|
||||
]
|
||||
else:
|
||||
query_filter["val"] = get_dttm_filter_value(
|
||||
filter_value, column, date_format
|
||||
)
|
||||
|
||||
return query_filters
|
||||
|
||||
Reference in New Issue
Block a user