From: Gord Thompson Date: Sun, 14 Jan 2024 16:49:11 +0000 (-0700) Subject: use ensure_closed() for async close, close() for terminate X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4201b90210dcf60f9830df299be016dee315753b;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git use ensure_closed() for async close, close() for terminate Fixed issue in asyncio dialects asyncmy and aiomysql, where their ``.close()`` method is apparently not a graceful close. replace with non-standard ``.ensure_closed()`` method that's awaitable and move ``.close()`` to the so-called "terminate" case. Fixes: #10893 Change-Id: I33d871e67854d85f770c46f699e41a6e73b6fbe0 --- diff --git a/doc/build/changelog/unreleased_20/10893.rst b/doc/build/changelog/unreleased_20/10893.rst new file mode 100644 index 0000000000..63507f38d5 --- /dev/null +++ b/doc/build/changelog/unreleased_20/10893.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, mysql + :tickets: 10893 + + Fixed issue in asyncio dialects asyncmy and aiomysql, where their + ``.close()`` method is apparently not a graceful close. replace with + non-standard ``.ensure_closed()`` method that's awaitable and move + ``.close()`` to the so-called "terminate" case. diff --git a/lib/sqlalchemy/dialects/mysql/aiomysql.py b/lib/sqlalchemy/dialects/mysql/aiomysql.py index 840a2bf5b4..315ea6df95 100644 --- a/lib/sqlalchemy/dialects/mysql/aiomysql.py +++ b/lib/sqlalchemy/dialects/mysql/aiomysql.py @@ -68,10 +68,13 @@ class AsyncAdapt_aiomysql_connection(AsyncAdapt_dbapi_connection): def autocommit(self, value): await_(self._connection.autocommit(value)) - def close(self): + def terminate(self): # it's not awaitable. self._connection.close() + def close(self) -> None: + await_(self._connection.ensure_closed()) + class AsyncAdapt_aiomysql_dbapi: def __init__(self, aiomysql, pymysql): @@ -136,6 +139,7 @@ class MySQLDialect_aiomysql(MySQLDialect_pymysql): _sscursor = AsyncAdapt_aiomysql_ss_cursor is_async = True + has_terminate = True @classmethod def import_dbapi(cls): @@ -143,6 +147,9 @@ class MySQLDialect_aiomysql(MySQLDialect_pymysql): __import__("aiomysql"), __import__("pymysql") ) + def do_terminate(self, dbapi_connection) -> None: + dbapi_connection.terminate() + def create_connect_args(self, url): return super().create_connect_args( url, _translate_args=dict(username="user", database="db") diff --git a/lib/sqlalchemy/dialects/mysql/asyncmy.py b/lib/sqlalchemy/dialects/mysql/asyncmy.py index 802546fb73..5fc36044dc 100644 --- a/lib/sqlalchemy/dialects/mysql/asyncmy.py +++ b/lib/sqlalchemy/dialects/mysql/asyncmy.py @@ -81,10 +81,13 @@ class AsyncAdapt_asyncmy_connection(AsyncAdapt_dbapi_connection): def autocommit(self, value): await_(self._connection.autocommit(value)) - def close(self): + def terminate(self): # it's not awaitable. self._connection.close() + def close(self) -> None: + await_(self._connection.ensure_closed()) + def _Binary(x): """Return x as a binary type.""" @@ -137,11 +140,15 @@ class MySQLDialect_asyncmy(MySQLDialect_pymysql): _sscursor = AsyncAdapt_asyncmy_ss_cursor is_async = True + has_terminate = True @classmethod def import_dbapi(cls): return AsyncAdapt_asyncmy_dbapi(__import__("asyncmy")) + def do_terminate(self, dbapi_connection) -> None: + dbapi_connection.terminate() + def create_connect_args(self, url): return super().create_connect_args( url, _translate_args=dict(username="user", database="db")