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 <grace....@airbnb.com>
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

Reply via email to