Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions superset/connectors/druid/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ class DruidClusterModelView(SupersetModelView, DeleteMixin, YamlExportMixin):
),
}

yaml_dict_key = "databases"

edit_form_extra_fields = {
"cluster_name": QuerySelectField(
"Cluster",
Expand Down
2 changes: 1 addition & 1 deletion superset/utils/import_datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def import_datasource(
"""Imports the datasource from the object to the database.

Metrics and columns and datasource will be overrided if exists.
This function can be used to import/export dashboards between multiple
This function can be used to import/export datasources between multiple
superset instances. Audit metadata isn't copies over.
"""
make_transient(i_datasource)
Expand Down
10 changes: 9 additions & 1 deletion superset/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import logging
import traceback
from datetime import datetime
from typing import Any, Dict
from typing import Any, Dict, Optional

import simplejson as json
import yaml
Expand Down Expand Up @@ -208,12 +208,20 @@ def validate_json(form, field):


class YamlExportMixin(object):
yaml_dict_key: Optional[str] = None
"""
Override this if you want a dict response instead, with a certain key.
Used on DatabaseView for cli compatibility
"""

@action("yaml_export", __("Export to YAML"), __("Export to YAML?"), "fa-download")
def yaml_export(self, items):
if not isinstance(items, list):
items = [items]

data = [t.export_to_dict() for t in items]
if self.yaml_dict_key:
data = {self.yaml_dict_key: data}
return Response(
yaml.safe_dump(data),
headers=generate_download_headers("yaml"),
Expand Down
2 changes: 2 additions & 0 deletions superset/views/database/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class DatabaseView(DatabaseMixin, SupersetModelView, DeleteMixin, YamlExportMixi
edit_template = "superset/models/database/edit.html"
validators_columns = {"sqlalchemy_uri": [sqlalchemy_uri_form_validator]}

yaml_dict_key = "databases"

def _delete(self, pk):
DeleteMixin._delete(self, pk)

Expand Down
21 changes: 21 additions & 0 deletions tests/dict_import_export_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from superset.connectors.druid.models import DruidColumn, DruidDatasource, DruidMetric
from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn
from superset.utils.core import get_example_database
from superset.utils.dict_import_export import export_to_dict

from .base_tests import SupersetTestCase

Expand Down Expand Up @@ -266,6 +267,26 @@ def test_import_table_override_identical(self):
imported_copy_table.export_to_dict(), imported_table.export_to_dict()
)

def test_export_datasource_ui_cli(self):
cli_export = export_to_dict(
session=db.session,
recursive=True,
back_references=False,
include_defaults=False,
)
self.get_resp("/login/", data=dict(username="admin", password="general"))
resp = self.get_resp(
"/databaseview/action_post", {"action": "yaml_export", "rowid": 1}
)
ui_export = yaml.safe_load(resp)
self.assertEqual(
ui_export["databases"][0]["database_name"],
cli_export["databases"][0]["database_name"],
)
self.assertEqual(
ui_export["databases"][0]["tables"], cli_export["databases"][0]["tables"]
)

def test_import_druid_no_metadata(self):
datasource, dict_datasource = self.create_druid_datasource(
"pure_druid", id=ID_PREFIX + 1
Expand Down