You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2024/12/05 23:27:05 UTC
(superset) 03/07: working
This is an automated email from the ASF dual-hosted git repository.
maximebeauchemin pushed a commit to branch sqla-close
in repository https://gitbox.apache.org/repos/asf/superset.git
commit f9ca78252f11ad3f21e1f60886bbcf5962c31690
Author: Maxime Beauchemin <ma...@gmail.com>
AuthorDate: Thu Dec 5 10:45:52 2024 -0800
working
---
superset/models/core.py | 55 +++++++++++++++---------------------
superset/sqllab/sql_json_executer.py | 5 ++--
2 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/superset/models/core.py b/superset/models/core.py
index 4e60ba0cb8..7d5b688a18 100755
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -95,53 +95,44 @@ if TYPE_CHECKING:
DB_CONNECTION_MUTATOR = config["DB_CONNECTION_MUTATOR"]
-def print_connection_status():
- logger.info("Pinging database")
- logger.info(f"STATUS: {db.session.connection().closed}")
-
- try:
- db.session.execute("SELECT 1")
- logger.info("success")
- except Exception:
- logger.error("connection failed as expected")
-
-
@contextmanager
-def temporarily_disconnect_metadata_db(): # type: ignore
+def temporarily_disconnect_db(): # type: ignore
"""
- Temporary disconnects the metadata database session during analytics query.
+ Temporary disconnects the metadata database session.
+
+ This is meant to be used during long, blocking operations, so that we can release
+ the database connection for the duration of, for example, a potentially long running
+ query against an analytics database.
+
The goal here is to lower the number of concurrent connections to the metadata database,
given that Superset has no control over the duration of the analytics query.
- If using a connection pool, the connn is release during the period. If not, the conn is closed
- and has to be re-established.
-
- Only has an effect if feature flag DISABLE_METADATA_DB_DURING_ANALYTICS is on
+ NOTE: only has an effect if feature flag DISABLE_METADATA_DB_DURING_ANALYTICS
+ and using NullPool
"""
- do_it = is_feature_enabled("DISABLE_METADATA_DB_DURING_ANALYTICS")
- connection = db.session.connection()
+ pool_type = db.engine.pool.__class__.__name__
+ # Currently only tested/available when used with NullPool
+ do_it = (
+ is_feature_enabled("DISABLE_METADATA_DB_DURING_ANALYTICS")
+ and pool_type == "NullPool"
+ )
+ conn = db.session.connection()
try:
if do_it:
logger.info("Disconnecting metadata database temporarily")
+ # Closing the session
db.session.close()
- print_connection_status()
- connection.close()
- logger.info(f"STATUS: {connection.closed}")
+ # Closing the connection
+ conn.close()
yield None
finally:
if do_it:
logger.info("Reconnecting to metadata database")
- logger.info("BEFORE")
- print_connection_status()
-
- # NOTE: Interface changes in flask-sqlalchemy 3.0
-
- db.session.connection()
+ conn = db.session.connection()
+ # Creating a new scoped session
+ # NOTE: Interface changes in flask-sqlalchemy ~3.0
db.session = db.create_scoped_session()
- logger.info("AFTER")
- print_connection_status()
-
class KeyValue(Model): # pylint: disable=too-few-public-methods
"""Used for any type of key-value store"""
@@ -739,7 +730,7 @@ class Database(Model, AuditMixinNullable, ImportExportMixin): # pylint: disable
with self.get_raw_connection(catalog=catalog, schema=schema) as conn:
cursor = conn.cursor()
df = None
- with temporarily_disconnect_metadata_db():
+ with temporarily_disconnect_db():
for i, sql_ in enumerate(sqls):
sql_ = self.mutate_sql_based_on_config(sql_, is_split=True)
_log_query(sql_)
diff --git a/superset/sqllab/sql_json_executer.py b/superset/sqllab/sql_json_executer.py
index 9ad70ca6ab..0c21410fe0 100644
--- a/superset/sqllab/sql_json_executer.py
+++ b/superset/sqllab/sql_json_executer.py
@@ -31,7 +31,7 @@ from superset.exceptions import (
SupersetGenericDBErrorException,
SupersetTimeoutException,
)
-from superset.models.core import temporarily_disconnect_metadata_db
+from superset.models.core import temporarily_disconnect_db
from superset.sqllab.command_status import SqlJsonExecutionStatus
from superset.utils import core as utils
from superset.utils.core import get_username
@@ -101,7 +101,6 @@ class SynchronousSqlJsonExecutor(SqlJsonExecutorBase):
except SupersetTimeoutException:
raise
except Exception as ex:
- raise ex
logger.exception("Query %i failed unexpectedly", query_id)
logger.error(ex)
raise SupersetGenericDBErrorException(
@@ -130,7 +129,7 @@ class SynchronousSqlJsonExecutor(SqlJsonExecutorBase):
seconds=self._timeout_duration_in_seconds,
error_message=self._get_timeout_error_msg(),
):
- with temporarily_disconnect_metadata_db():
+ with temporarily_disconnect_db():
return self._get_sql_results(
execution_context, rendered_query, log_params
)