diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-10-11 14:22:40 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-10-11 14:29:28 -0400 |
| commit | 9d132a7cf96678a732b06266fa0a35279268604b (patch) | |
| tree | 5fc9b7d66c9d3455ebe3a34eb7a8d117bc37793c /lib/sqlalchemy/dialects/sqlite | |
| parent | 4041dec5dab99f0b7351f322d942438b106aa467 (diff) | |
| download | sqlalchemy-9d132a7cf96678a732b06266fa0a35279268604b.tar.gz | |
enable check same thread for aiosqlite
to do this we have to invent our own isolation level
setter based on their current internals. however
now we can ensure thread-safe access. we are trying
to resolve an issue where test suite on CI seems to fail
around the same time each time.
Change-Id: I79c8fc04b9afef0876fb446ad40a7621a772cd34
Diffstat (limited to 'lib/sqlalchemy/dialects/sqlite')
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/aiosqlite.py | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/lib/sqlalchemy/dialects/sqlite/aiosqlite.py b/lib/sqlalchemy/dialects/sqlite/aiosqlite.py index 97ea1b2b3..c3926e121 100644 --- a/lib/sqlalchemy/dialects/sqlite/aiosqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/aiosqlite.py @@ -47,6 +47,9 @@ in Python and use them directly in SQLite queries as described here: :ref:`pysql """ # noqa +import asyncio +from functools import partial + from .base import SQLiteExecutionContext from .pysqlite import SQLiteDialect_pysqlite from ... import pool @@ -187,8 +190,22 @@ class AsyncAdapt_aiosqlite_connection(AdaptedConnection): @isolation_level.setter def isolation_level(self, value): + + # aiosqlite's isolation_level setter works outside the Thread + # that it's supposed to, necessitating setting check_same_thread=False. + # for improved stability, we instead invent our own awaitable version + # using aiosqlite's async queue directly. + + def set_iso(connection, value): + connection.isolation_level = value + + function = partial(set_iso, self._connection._conn, value) + future = asyncio.get_event_loop().create_future() + + self._connection._tx.put_nowait((future, function)) + try: - self._connection.isolation_level = value + return self.await_(future) except Exception as error: self._handle_exception(error) @@ -272,18 +289,6 @@ class AsyncAdapt_aiosqlite_dbapi: def connect(self, *arg, **kw): async_fallback = kw.pop("async_fallback", False) - # Q. WHY do we need this? - # A. Because there is no way to set connection.isolation_level - # otherwise - # Q. BUT HOW do you know it is SAFE ????? - # A. The only operation that isn't safe is the isolation level set - # operation which aiosqlite appears to have let slip through even - # though pysqlite appears to do check_same_thread for this. - # All execute operations etc. should be safe because they all - # go through the single executor thread. - - kw["check_same_thread"] = False - connection = self.aiosqlite.connect(*arg, **kw) # it's a Thread. you'll thank us later |
