diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 40eb25e02..680577799 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -42,6 +42,7 @@ from sqlalchemy import ( ) from sqlalchemy.exc import CompileError from sqlalchemy.orm import backref, relationship +from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.schema import UniqueConstraint from sqlalchemy.sql import column, literal_column, table, text from sqlalchemy.sql.expression import Label, TextAsFrom @@ -50,6 +51,7 @@ import sqlparse from superset import app, db, security_manager from superset.connectors.base.models import BaseColumn, BaseDatasource, BaseMetric from superset.db_engine_specs.base import TimestampExpression +from superset.exceptions import DatabaseNotFound from superset.jinja_context import get_template_processor from superset.models.annotations import Annotation from superset.models.core import Database @@ -1005,11 +1007,19 @@ class SqlaTable(Model, BaseDatasource): ) def lookup_database(table): - return ( - db.session.query(Database) - .filter_by(database_name=table.params_dict["database_name"]) - .one() - ) + try: + return ( + db.session.query(Database) + .filter_by(database_name=table.params_dict["database_name"]) + .one() + ) + except NoResultFound: + raise DatabaseNotFound( + _( + "Database '%(name)s' is not found", + name=table.params_dict["database_name"], + ) + ) return import_datasource.import_datasource( db.session, i_datasource, lookup_database, lookup_sqlatable, import_time diff --git a/superset/exceptions.py b/superset/exceptions.py index ae491fc8d..ade6ef81c 100644 --- a/superset/exceptions.py +++ b/superset/exceptions.py @@ -54,3 +54,7 @@ class SupersetTemplateException(SupersetException): class SpatialException(SupersetException): pass + + +class DatabaseNotFound(SupersetException): + status = 400 diff --git a/superset/views/core.py b/superset/views/core.py index 6d18176c6..5cedfe1c1 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -64,7 +64,11 @@ from superset import ( ) from superset.connectors.connector_registry import ConnectorRegistry from superset.connectors.sqla.models import AnnotationDatasource, SqlaTable -from superset.exceptions import SupersetException, SupersetSecurityException +from superset.exceptions import ( + DatabaseNotFound, + SupersetException, + SupersetSecurityException, +) from superset.forms import CsvToDatabaseForm from superset.jinja_context import get_template_processor from superset.legacy import update_time_range @@ -1441,7 +1445,26 @@ class Superset(BaseSupersetView): """Overrides the dashboards using json instances from the file.""" f = request.files.get("file") if request.method == "POST" and f: - dashboard_import_export.import_dashboards(db.session, f.stream) + try: + dashboard_import_export.import_dashboards(db.session, f.stream) + except DatabaseNotFound as e: + flash( + _( + "Cannot import dashboard: %(db_error)s.\n" + "Make sure to create the database before " + "importing the dashboard.", + db_error=e, + ), + "danger", + ) + except Exception: + flash( + _( + "An unknown error occurred. " + "Please contact your Superset administrator" + ), + "danger", + ) return redirect("/dashboard/list/") return self.render_template("superset/import_dashboards.html")