summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/sqlite
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-10-11 14:22:40 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-10-11 14:29:28 -0400
commit9d132a7cf96678a732b06266fa0a35279268604b (patch)
tree5fc9b7d66c9d3455ebe3a34eb7a8d117bc37793c /lib/sqlalchemy/dialects/sqlite
parent4041dec5dab99f0b7351f322d942438b106aa467 (diff)
downloadsqlalchemy-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.py31
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