diff --git a/superset/utils/core.py b/superset/utils/core.py index 65d6e4e4c..3a4b18c1b 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -39,7 +39,6 @@ from typing import Any, Dict, Iterator, List, NamedTuple, Optional, Tuple, Union from urllib.parse import unquote_plus import bleach -import celery import markdown as md import numpy import pandas as pd @@ -47,10 +46,9 @@ import parsedatetime import sqlalchemy as sa from dateutil.parser import parse from dateutil.relativedelta import relativedelta -from flask import current_app, flash, Flask, g, Markup, render_template +from flask import current_app, flash, g, Markup, render_template from flask_appbuilder.security.sqla.models import User from flask_babel import gettext as __, lazy_gettext as _ -from flask_caching import Cache from sqlalchemy import event, exc, select, Text from sqlalchemy.dialects.mysql import MEDIUMTEXT from sqlalchemy.sql.type_api import Variant @@ -252,30 +250,6 @@ def dttm_from_timetuple(d: struct_time) -> datetime: return datetime(d.tm_year, d.tm_mon, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec) -def decode_dashboards(o): - """ - Function to be passed into json.loads obj_hook parameter - Recreates the dashboard object from a json representation. - """ - import superset.models.core as models - from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn - - if "__Dashboard__" in o: - return models.Dashboard(**o["__Dashboard__"]) - elif "__Slice__" in o: - return models.Slice(**o["__Slice__"]) - elif "__TableColumn__" in o: - return TableColumn(**o["__TableColumn__"]) - elif "__SqlaTable__" in o: - return SqlaTable(**o["__SqlaTable__"]) - elif "__SqlMetric__" in o: - return SqlMetric(**o["__SqlMetric__"]) - elif "__datetime__" in o: - return datetime.strptime(o["__datetime__"], "%Y-%m-%dT%H:%M:%S") - else: - return o - - class DashboardEncoder(json.JSONEncoder): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/superset/utils/dashboard_import_export.py b/superset/utils/dashboard_import_export.py index b35740833..dc8d59f2e 100644 --- a/superset/utils/dashboard_import_export.py +++ b/superset/utils/dashboard_import_export.py @@ -18,9 +18,33 @@ import json import logging import time +from datetime import datetime -from superset.models.core import Dashboard -from superset.utils.core import decode_dashboards +from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn +from superset.models.core import Dashboard, Slice + + +def decode_dashboards(o): + """ + Function to be passed into json.loads obj_hook parameter + Recreates the dashboard object from a json representation. + """ + import superset.models.core as models + + if "__Dashboard__" in o: + return Dashboard(**o["__Dashboard__"]) + elif "__Slice__" in o: + return Slice(**o["__Slice__"]) + elif "__TableColumn__" in o: + return TableColumn(**o["__TableColumn__"]) + elif "__SqlaTable__" in o: + return SqlaTable(**o["__SqlaTable__"]) + elif "__SqlMetric__" in o: + return SqlMetric(**o["__SqlMetric__"]) + elif "__datetime__" in o: + return datetime.strptime(o["__datetime__"], "%Y-%m-%dT%H:%M:%S") + else: + return o def import_dashboards(session, data_stream, import_time=None): diff --git a/tests/import_export_tests.py b/tests/import_export_tests.py index 2641e35ad..35e0d6598 100644 --- a/tests/import_export_tests.py +++ b/tests/import_export_tests.py @@ -22,12 +22,12 @@ import unittest from flask import g from sqlalchemy.orm.session import make_transient +from superset.utils.dashboard_import_export import decode_dashboards from tests.test_app import app from superset import db, security_manager from superset.connectors.druid.models import DruidColumn, DruidDatasource, DruidMetric from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn from superset.models import core as models -from superset.utils import core as utils from .base_tests import SupersetTestCase @@ -229,7 +229,7 @@ class ImportExportTests(SupersetTestCase): ) resp = self.client.get(export_dash_url) exported_dashboards = json.loads( - resp.data.decode("utf-8"), object_hook=utils.decode_dashboards + resp.data.decode("utf-8"), object_hook=decode_dashboards )["dashboards"] birth_dash = self.get_dash_by_slug("births") @@ -238,13 +238,12 @@ class ImportExportTests(SupersetTestCase): self.assertEqual( birth_dash.id, json.loads( - exported_dashboards[0].json_metadata, - object_hook=utils.decode_dashboards, + exported_dashboards[0].json_metadata, object_hook=decode_dashboards )["remote_id"], ) exported_tables = json.loads( - resp.data.decode("utf-8"), object_hook=utils.decode_dashboards + resp.data.decode("utf-8"), object_hook=decode_dashboards )["datasources"] self.assertEqual(1, len(exported_tables)) self.assert_table_equals( @@ -259,9 +258,7 @@ class ImportExportTests(SupersetTestCase): birth_dash.id, world_health_dash.id ) resp = self.client.get(export_dash_url) - resp_data = json.loads( - resp.data.decode("utf-8"), object_hook=utils.decode_dashboards - ) + resp_data = json.loads(resp.data.decode("utf-8"), object_hook=decode_dashboards) exported_dashboards = sorted( resp_data.get("dashboards"), key=lambda d: d.dashboard_title )