mirror of https://github.com/apache/superset.git
feat: update IDs when importing dashboards (#11991)
* feat: update IDs when importing dashboards * Fix typos
This commit is contained in:
parent
9277a54a12
commit
45703a1dea
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue