This is an automated email from the ASF dual-hosted git repository.
graceguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 421aeb4 [dashboard] fix filter_scopes when copy dashboard with
duplicate_slices (#9188)
421aeb4 is described below
commit 421aeb4605173bbb162a2aff4855ac49ea1b3e40
Author: Grace Guo <[email protected]>
AuthorDate: Mon Feb 24 13:45:29 2020 -0800
[dashboard] fix filter_scopes when copy dashboard with duplicate_slices
(#9188)
* [dashboard] fix filter_scopes when copy dashboard with duplicate_slices
* code cleanup
---
superset/models/dashboard.py | 21 +++++++++++----------
superset/utils/dashboard_filter_scopes_converter.py | 14 ++++++++++++++
superset/views/core.py | 19 +++++++++++++------
3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/superset/models/dashboard.py b/superset/models/dashboard.py
index 60af209..ae9ed5f 100644
--- a/superset/models/dashboard.py
+++ b/superset/models/dashboard.py
@@ -44,7 +44,10 @@ from superset.models.slice import Slice as Slice
from superset.models.tags import DashboardUpdater
from superset.models.user_attributes import UserAttribute
from superset.utils import core as utils
-from superset.utils.dashboard_filter_scopes_converter import
convert_filter_scopes
+from superset.utils.dashboard_filter_scopes_converter import (
+ convert_filter_scopes,
+ copy_filter_scopes,
+)
if TYPE_CHECKING:
# pylint: disable=unused-import
@@ -288,10 +291,10 @@ class Dashboard( # pylint:
disable=too-many-instance-attributes
# and will remove the existing dashboard - slice association
slices = copy(dashboard_to_import.slices)
old_json_metadata = json.loads(dashboard_to_import.json_metadata or
"{}")
- old_to_new_slc_id_dict = {}
+ old_to_new_slc_id_dict: Dict[int, int] = {}
new_timed_refresh_immune_slices = []
new_expanded_slices = {}
- new_filter_scopes = {}
+ new_filter_scopes: Dict[str, Dict] = {}
i_params_dict = dashboard_to_import.params_dict
remote_id_slice_map = {
slc.params_dict["remote_id"]: slc
@@ -338,13 +341,11 @@ class Dashboard( # pylint:
disable=too-many-instance-attributes
filter_scopes = old_json_metadata.get("filter_scopes")
# then replace old slice id to new slice id:
- for (slice_id, scopes) in filter_scopes.items():
- new_filter_key = old_to_new_slc_id_dict[int(slice_id)]
- new_filter_scopes[str(new_filter_key)] = scopes
- for scope in scopes.values():
- scope["immune"] = [
- old_to_new_slc_id_dict[slice_id] for slice_id in
scope.get("immune")
- ]
+ if filter_scopes:
+ new_filter_scopes = copy_filter_scopes(
+ old_to_new_slc_id_dict=old_to_new_slc_id_dict,
+ old_filter_scopes=filter_scopes,
+ )
# override the dashboard
existing_dashboard = None
diff --git a/superset/utils/dashboard_filter_scopes_converter.py
b/superset/utils/dashboard_filter_scopes_converter.py
index 7fff9dd..6546479 100644
--- a/superset/utils/dashboard_filter_scopes_converter.py
+++ b/superset/utils/dashboard_filter_scopes_converter.py
@@ -70,3 +70,17 @@ def convert_filter_scopes(json_metadata: Dict, filters:
List[Slice]):
filter_scopes[filter_id] = filter_fields
return filter_scopes
+
+
+def copy_filter_scopes(
+ old_to_new_slc_id_dict: Dict[int, int], old_filter_scopes: Dict[str, Dict]
+) -> Dict:
+ new_filter_scopes = {}
+ for (slice_id, scopes) in old_filter_scopes.items():
+ new_filter_key = old_to_new_slc_id_dict[int(slice_id)]
+ new_filter_scopes[str(new_filter_key)] = scopes
+ for scope in scopes.values():
+ scope["immune"] = [
+ old_to_new_slc_id_dict[slice_id] for slice_id in
scope.get("immune")
+ ]
+ return new_filter_scopes
diff --git a/superset/views/core.py b/superset/views/core.py
index 0a7872e..d876643 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -81,6 +81,7 @@ from superset.models.user_attributes import UserAttribute
from superset.sql_parse import ParsedQuery
from superset.sql_validators import get_validator_by_name
from superset.utils import core as utils, dashboard_import_export
+from superset.utils.dashboard_filter_scopes_converter import copy_filter_scopes
from superset.utils.dates import now_as_float
from superset.utils.decorators import etag_cache, stats_timing
from superset.views.database.filters import DatabaseFilter
@@ -1177,27 +1178,33 @@ class Superset(BaseSupersetView):
if data["duplicate_slices"]:
# Duplicating slices as well, mapping old ids to new ones
- old_to_new_sliceids = {}
+ old_to_new_sliceids: Dict[int, int] = {}
for slc in original_dash.slices:
new_slice = slc.clone()
new_slice.owners = [g.user] if g.user else []
session.add(new_slice)
session.flush()
new_slice.dashboards.append(dash)
- old_to_new_sliceids["{}".format(slc.id)] =
"{}".format(new_slice.id)
+ old_to_new_sliceids[slc.id] = new_slice.id
# update chartId of layout entities
- # in v2_dash positions json data, chartId should be integer,
- # while in older version slice_id is string type
for value in data["positions"].values():
if (
isinstance(value, dict)
and value.get("meta")
and value.get("meta").get("chartId")
):
- old_id = "{}".format(value.get("meta").get("chartId"))
- new_id = int(old_to_new_sliceids[old_id])
+ old_id = value.get("meta").get("chartId")
+ new_id = old_to_new_sliceids[old_id]
value["meta"]["chartId"] = new_id
+
+ # replace filter_id and immune ids from old slice id to new slice
id:
+ if "filter_scopes" in data:
+ new_filter_scopes = copy_filter_scopes(
+ old_to_new_slc_id_dict=old_to_new_sliceids,
+ old_filter_scopes=json.loads(data["filter_scopes"] or
"{}"),
+ )
+ data["filter_scopes"] = json.dumps(new_filter_scopes)
else:
dash.slices = original_dash.slices
dash.params = original_dash.params