fitzee commented on code in PR #40194:
URL: https://github.com/apache/superset/pull/40194#discussion_r3255723568


##########
superset/models/core.py:
##########
@@ -468,13 +468,31 @@ def get_sqla_engine(  # pylint: disable=too-many-arguments
             engine_context_manager = app.config["ENGINE_CONTEXT_MANAGER"]
             with engine_context_manager(self, catalog, schema):
                 with check_for_oauth2(self):
-                    yield self._get_sqla_engine(
+                    engine = self._get_sqla_engine(
                         catalog=catalog,
                         schema=schema,
                         nullpool=nullpool,
                         source=source,
                         sqlalchemy_uri=sqlalchemy_uri,
                     )
+                    prequeries = self.db_engine_spec.get_prequeries(
+                        database=self,
+                        catalog=catalog,
+                        schema=schema,
+                    )
+                    if prequeries:
+
+                        def run_prequeries(
+                            dbapi_connection: Any,
+                            connection_record: Any,  # pylint: 
disable=unused-argument
+                        ) -> None:
+                            cursor = dbapi_connection.cursor()
+                            for prequery in prequeries:
+                                cursor.execute(prequery)
+                            cursor.close()
+
+                        sqla.event.listen(engine, "connect", run_prequeries)
+                    yield engine

Review Comment:
   Fixed in commit 
[0ceaf8ff11](https://github.com/fitzee/superset/commit/0ceaf8ff11390001db6f0b49a8fd13b331280857):
 the manual `get_prequeries()` loop was removed from `get_raw_connection()` 
entirely. The connect event listener registered by `get_sqla_engine()` is now 
the sole execution point, so prequeries fire exactly once regardless of which 
call path is used.
   
   Regression test added in commit 
[97fd0e4882](https://github.com/fitzee/superset/commit/97fd0e4882e9f35a5b9afb9ae2ceade4bb2e07c8):
 `test_get_raw_connection_executes_prequeries_exactly_once` intercepts 
`sqla.event.listen`, simulates SQLAlchemy firing the connect event when 
`raw_connection()` is called, and asserts `cursor.execute` is called exactly 
once — not twice, not zero.



##########
superset/models/core.py:
##########
@@ -468,13 +468,31 @@ def get_sqla_engine(  # pylint: disable=too-many-arguments
             engine_context_manager = app.config["ENGINE_CONTEXT_MANAGER"]
             with engine_context_manager(self, catalog, schema):
                 with check_for_oauth2(self):
-                    yield self._get_sqla_engine(
+                    engine = self._get_sqla_engine(
                         catalog=catalog,
                         schema=schema,
                         nullpool=nullpool,
                         source=source,
                         sqlalchemy_uri=sqlalchemy_uri,
                     )
+                    prequeries = self.db_engine_spec.get_prequeries(
+                        database=self,
+                        catalog=catalog,
+                        schema=schema,
+                    )
+                    if prequeries:
+
+                        def run_prequeries(
+                            dbapi_connection: Any,
+                            connection_record: Any,  # pylint: 
disable=unused-argument
+                        ) -> None:
+                            cursor = dbapi_connection.cursor()
+                            for prequery in prequeries:
+                                cursor.execute(prequery)
+                            cursor.close()

Review Comment:
   Fixed in commit 
[c9b1d64dee](https://github.com/fitzee/superset/commit/c9b1d64dee9b1f0fb7d90543f9d3bcd17b9d0447):
 `run_prequeries` now wraps cursor usage in `try/finally`, so `cursor.close()` 
is called unconditionally even when a prequery raises.
   
   Test added in the same commit: 
`test_get_sqla_engine_prequery_cursor_closed_on_exception` injects an exception 
from `cursor.execute` and asserts `cursor.close` is still called exactly once.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to