feat: update IDs when importing dashboards (#11991)

* feat: update IDs when importing dashboards

* Fix typos
This commit is contained in:
Beto Dealmeida 2020-12-11 18:19:36 -08:00 committed by GitHub
parent 9277a54a12
commit 45703a1dea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 11 deletions

View File

@ -25,7 +25,10 @@ from superset.charts.commands.importers.v1.utils import import_chart
from superset.charts.schemas import ImportV1ChartSchema
from superset.commands.importers.v1 import ImportModelsCommand
from superset.dashboards.commands.exceptions import DashboardImportError
from superset.dashboards.commands.importers.v1.utils import import_dashboard
from superset.dashboards.commands.importers.v1.utils import (
import_dashboard,
update_id_refs,
)
from superset.dashboards.dao import DashboardDAO
from superset.dashboards.schemas import ImportV1DashboardSchema
from superset.databases.commands.importers.v1.utils import import_database
@ -128,8 +131,8 @@ class ImportDashboardsCommand(ImportModelsCommand):
dashboard_chart_ids: List[Tuple[int, int]] = []
for file_name, config in configs.items():
if file_name.startswith("dashboards/"):
config = update_id_refs(config, chart_ids)
dashboard = import_dashboard(session, config, overwrite=overwrite)
for uuid in find_chart_uuids(config["position"]):
chart_id = chart_ids[uuid]
if (dashboard.id, chart_id) not in existing_relationships:

View File

@ -29,6 +29,70 @@ logger = logging.getLogger(__name__)
JSON_KEYS = {"position": "position_json", "metadata": "json_metadata"}
def build_uuid_to_id_map(position: Dict[str, Any]) -> Dict[str, int]:
return {
child["meta"]["uuid"]: child["meta"]["chartId"]
for child in position.values()
if (
isinstance(child, dict)
and child["type"] == "CHART"
and "uuid" in child["meta"]
)
}
def update_id_refs(config: Dict[str, Any], chart_ids: Dict[str, int]) -> Dict[str, Any]:
"""Update dashboard metadata to use new IDs"""
if not config.get("metadata"):
return config
fixed = config.copy()
# build map old_id => new_id
old_ids = build_uuid_to_id_map(fixed["position"])
id_map = {old_id: chart_ids[uuid] for uuid, old_id in old_ids.items()}
# fix metadata
metadata = fixed["metadata"]
if "timed_refresh_immune_slices" in metadata:
metadata["timed_refresh_immune_slices"] = [
id_map[old_id] for old_id in metadata["timed_refresh_immune_slices"]
]
if "filter_scopes" in metadata:
# in filter_scopes the key is the chart ID as a string; we need to udpate
# them to be the new ID as a string:
metadata["filter_scopes"] = {
str(id_map[int(old_id)]): columns
for old_id, columns in metadata["filter_scopes"].items()
}
# now update columns to use new IDs:
for columns in metadata["filter_scopes"].values():
for attributes in columns.values():
attributes["immune"] = [
id_map[old_id] for old_id in attributes["immune"]
]
if "expanded_slices" in metadata:
metadata["expanded_slices"] = {
str(id_map[int(old_id)]): value
for old_id, value in metadata["expanded_slices"].items()
}
# fix position
position = fixed["position"]
for child in position.values():
if (
isinstance(child, dict)
and child["type"] == "CHART"
and "uuid" in child["meta"]
):
child["meta"]["chartId"] = chart_ids[child["meta"]["uuid"]]
return fixed
def import_dashboard(
session: Session, config: Dict[str, Any], overwrite: bool = False
) -> Dashboard:

View File

@ -263,6 +263,12 @@ class TestImportDashboardsCommand(SupersetTestCase):
dashboard = (
db.session.query(Dashboard).filter_by(uuid=dashboard_config["uuid"]).one()
)
assert len(dashboard.slices) == 1
chart = dashboard.slices[0]
assert str(chart.uuid) == chart_config["uuid"]
new_chart_id = chart.id
assert dashboard.dashboard_title == "Test dash"
assert dashboard.description is None
assert dashboard.css == ""
@ -272,7 +278,7 @@ class TestImportDashboardsCommand(SupersetTestCase):
"children": [],
"id": "CHART-SVAlICPOSJ",
"meta": {
"chartId": 83,
"chartId": new_chart_id,
"height": 50,
"sliceName": "Number of California Births",
"uuid": "0c23747a-6528-4629-97bf-e4b78d3b9df1",
@ -305,17 +311,18 @@ class TestImportDashboardsCommand(SupersetTestCase):
assert json.loads(dashboard.json_metadata) == {
"color_scheme": None,
"default_filters": "{}",
"expanded_slices": {},
"expanded_slices": {str(new_chart_id): True},
"filter_scopes": {
str(new_chart_id): {
"region": {"scope": ["ROOT_ID"], "immune": [new_chart_id]}
},
},
"import_time": 1604342885,
"refresh_frequency": 0,
"remote_id": 7,
"timed_refresh_immune_slices": [],
"timed_refresh_immune_slices": [new_chart_id],
}
assert len(dashboard.slices) == 1
chart = dashboard.slices[0]
assert str(chart.uuid) == chart_config["uuid"]
dataset = chart.table
assert str(dataset.uuid) == dataset_config["uuid"]

View File

@ -488,8 +488,9 @@ dashboard_config = {
},
},
"metadata": {
"timed_refresh_immune_slices": [],
"expanded_slices": {},
"timed_refresh_immune_slices": [83],
"filter_scopes": {"83": {"region": {"scope": ["ROOT_ID"], "immune": [83]}},},
"expanded_slices": {"83": True},
"refresh_frequency": 0,
"default_filters": "{}",
"color_scheme": None,