superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: Refactor testconn to use get_sqla_engine (#7717)
Date Tue, 09 Jul 2019 04:09:14 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 953e5c7  Refactor testconn to use get_sqla_engine (#7717)
953e5c7 is described below

commit 953e5c7a72acef34fc9447249c25db4e92ed5370
Author: Thoralf Gutierrez <thgutierrez@tesla.com>
AuthorDate: Mon Jul 8 21:09:06 2019 -0700

    Refactor testconn to use get_sqla_engine (#7717)
    
    Creating the database connection will actually go through the get_sqla_engine path so
that's what should be used to test the connection. This was triggered by realizing that testconn
was not using the DB_CONNECTION_MUTATOR hook.
    
    See #7668
---
 superset/views/core.py | 58 +++++++++++++++++---------------------------------
 1 file changed, 20 insertions(+), 38 deletions(-)

diff --git a/superset/views/core.py b/superset/views/core.py
index 16402d1..923e6b4 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -44,8 +44,7 @@ from flask_babel import gettext as __
 from flask_babel import lazy_gettext as _
 import pandas as pd
 import simplejson as json
-from sqlalchemy import and_, create_engine, MetaData, or_, select
-from sqlalchemy.engine.url import make_url
+from sqlalchemy import and_, MetaData, or_, select
 from sqlalchemy.exc import IntegrityError
 from werkzeug.routing import BaseConverter
 from werkzeug.utils import secure_filename
@@ -2014,47 +2013,32 @@ class Superset(BaseSupersetView):
     def testconn(self):
         """Tests a sqla connection"""
         try:
-            username = g.user.username if g.user is not None else None
-            uri = request.json.get("uri")
             db_name = request.json.get("name")
-            impersonate_user = request.json.get("impersonate_user")
-            database = None
+            uri = request.json.get("uri")
+
+            # if the database already exists in the database, only its safe (password-masked)
URI
+            # would be shown in the UI and would be passed in the form data.
+            # so if the database already exists and the form was submitted with the safe
URI,
+            # we assume we should retrieve the decrypted URI to test the connection.
             if db_name:
-                database = (
+                existing_database = (
                     db.session.query(models.Database)
                     .filter_by(database_name=db_name)
                     .first()
                 )
-                if database and uri == database.safe_sqlalchemy_uri():
-                    # the password-masked uri was passed
-                    # use the URI associated with this database
-                    uri = database.sqlalchemy_uri_decrypted
-
-            configuration = {}
-
-            if database and uri:
-                url = make_url(uri)
-                db_engine = models.Database.get_db_engine_spec_for_backend(
-                    url.get_backend_name()
-                )
-                db_engine.patch()
-
-                masked_url = database.get_password_masked_url_from_uri(uri)
-                logging.info("Superset.testconn(). Masked URL: {0}".format(masked_url))
+                if existing_database and uri == existing_database.safe_sqlalchemy_uri():
+                    uri = existing_database.sqlalchemy_uri_decrypted
 
-                configuration.update(
-                    db_engine.get_configuration_for_impersonation(
-                        uri, impersonate_user, username
-                    )
-                )
-
-            engine_params = request.json.get("extras", {}).get("engine_params", {})
-            connect_args = engine_params.get("connect_args")
-
-            if configuration and connect_args is not None:
-                connect_args["configuration"] = configuration
+            # this is the database instance that will be tested
+            database = models.Database(
+                # extras is sent as json, but required to be a string in the Database model
+                extra=json.dumps(request.json.get("extras", {})),
+                impersonate_user=request.json.get("impersonate_user"),
+            )
+            database.set_sqlalchemy_uri(uri)
 
-            engine = create_engine(uri, **engine_params)
+            username = g.user.username if g.user is not None else None
+            engine = database.get_sqla_engine(user_name=username)
 
             with closing(engine.connect()) as conn:
                 conn.scalar(select([1]))
@@ -2062,9 +2046,7 @@ class Superset(BaseSupersetView):
         except Exception as e:
             logging.exception(e)
             return json_error_response(
-                ("Connection failed!\n\n" "The error message returned was:\n{}").format(
-                    e
-                )
+                "Connection failed!\n\n" "The error message returned was:\n{}".format(e)
             )
 
     @api


Mime
View raw message