From ad6637c5d4c9e4a6f351b01256e44791b2822c51 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" Date: Tue, 2 May 2023 10:09:11 -0300 Subject: [PATCH 1/3] feat: Considers GENERIC_CHART_AXES in migrations --- .../migrations/shared/migrate_viz/base.py | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/superset/migrations/shared/migrate_viz/base.py b/superset/migrations/shared/migrate_viz/base.py index 024a58463e252..4fe2d831ca5e7 100644 --- a/superset/migrations/shared/migrate_viz/base.py +++ b/superset/migrations/shared/migrate_viz/base.py @@ -16,14 +16,15 @@ # under the License. from __future__ import annotations +import copy import json -from typing import Dict, Set +from typing import Any, Dict, Set from alembic import op from sqlalchemy import and_, Column, Integer, String, Text from sqlalchemy.ext.declarative import declarative_base -from superset import db +from superset import db, is_feature_enabled from superset.migrations.shared.utils import paginated_update, try_load_json Base = declarative_base() @@ -52,7 +53,7 @@ def __init__(self, form_data: str) -> None: self.data = try_load_json(form_data) def _pre_action(self) -> None: - """some actions before migrate""" + """Some actions before migrate""" def _migrate(self) -> None: if self.data.get("viz_type") != self.source_viz_type: @@ -68,22 +69,51 @@ def _migrate(self) -> None: if key in self.rename_keys: rv_data[self.rename_keys[key]] = value + continue if key in self.remove_keys: continue rv_data[key] = value + generic_chart_axes = is_feature_enabled("GENERIC_CHART_AXES") + if generic_chart_axes: + self._migrate_temporal_filter(rv_data) + self.data = rv_data def _post_action(self) -> None: - """some actions after migrate""" + """Some actions after migrate""" + + def _migrate_temporal_filter(self, rv_data: Dict[str, Any]) -> None: + """Adds a temporal filter.""" + granularity_sqla = rv_data.pop("granularity_sqla", None) + time_range = rv_data.pop("time_range", None) + + if not granularity_sqla or not time_range: + return + + temporal_filter = { + "clause": "WHERE", + "subject": granularity_sqla, + "operator": "TEMPORAL_RANGE", + "comparator": time_range, + "expressionType": "SIMPLE", + } + + if isinstance(granularity_sqla, dict): + temporal_filter["comparator"] = None + temporal_filter["expressionType"] = "SQL" + temporal_filter["subject"] = granularity_sqla["label"] + temporal_filter["sqlExpression"] = granularity_sqla["sqlExpression"] + + rv_data["adhoc_filters"] = rv_data.get("adhoc_filters", []) + [temporal_filter] @classmethod def upgrade_slice(cls, slc: Slice) -> Slice: clz = cls(slc.params) slc.viz_type = cls.target_viz_type - form_data_bak = clz.data.copy() + form_data_bak = copy.deepcopy(clz.data) clz._pre_action() clz._migrate() From c3a78379a30ee80e15c0d723ce2d3c59537dc80c Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" Date: Tue, 2 May 2023 10:45:24 -0300 Subject: [PATCH 2/3] Uses DEFAULT_TIME_FILTER in time_range if needed --- superset/migrations/shared/migrate_viz/base.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/superset/migrations/shared/migrate_viz/base.py b/superset/migrations/shared/migrate_viz/base.py index 4fe2d831ca5e7..dbb50f13faa93 100644 --- a/superset/migrations/shared/migrate_viz/base.py +++ b/superset/migrations/shared/migrate_viz/base.py @@ -24,7 +24,7 @@ from sqlalchemy import and_, Column, Integer, String, Text from sqlalchemy.ext.declarative import declarative_base -from superset import db, is_feature_enabled +from superset import conf, db, is_feature_enabled from superset.migrations.shared.utils import paginated_update, try_load_json Base = declarative_base() @@ -76,8 +76,7 @@ def _migrate(self) -> None: rv_data[key] = value - generic_chart_axes = is_feature_enabled("GENERIC_CHART_AXES") - if generic_chart_axes: + if is_feature_enabled("GENERIC_CHART_AXES"): self._migrate_temporal_filter(rv_data) self.data = rv_data @@ -88,9 +87,9 @@ def _post_action(self) -> None: def _migrate_temporal_filter(self, rv_data: Dict[str, Any]) -> None: """Adds a temporal filter.""" granularity_sqla = rv_data.pop("granularity_sqla", None) - time_range = rv_data.pop("time_range", None) + time_range = rv_data.pop("time_range", conf.get("DEFAULT_TIME_FILTER")) - if not granularity_sqla or not time_range: + if not granularity_sqla: return temporal_filter = { From 665ba6aafebc394e2346e5484cd38fed7fe949c3 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Tue, 2 May 2023 15:16:19 -0300 Subject: [PATCH 3/3] Adds safe guard Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com> --- superset/migrations/shared/migrate_viz/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset/migrations/shared/migrate_viz/base.py b/superset/migrations/shared/migrate_viz/base.py index dbb50f13faa93..e73cddd82d376 100644 --- a/superset/migrations/shared/migrate_viz/base.py +++ b/superset/migrations/shared/migrate_viz/base.py @@ -87,7 +87,7 @@ def _post_action(self) -> None: def _migrate_temporal_filter(self, rv_data: Dict[str, Any]) -> None: """Adds a temporal filter.""" granularity_sqla = rv_data.pop("granularity_sqla", None) - time_range = rv_data.pop("time_range", conf.get("DEFAULT_TIME_FILTER")) + time_range = rv_data.pop("time_range", None) or conf.get("DEFAULT_TIME_FILTER") if not granularity_sqla: return