From https://github.com/litestar-org/litestar/actions/runs/9039276158/job/24841832854?pr=3486
________________________________ test_sync_app _________________________________
[gw0] linux -- Python 3.8.18 /home/runner/work/litestar/litestar/.venv/bin/python
self = <sqlalchemy.engine.base.Connection object at 0x7efe10fc11f0>
def _rollback_impl(self) -> None:
if self._has_events or self.engine._has_events:
self.dispatch.rollback(self)
if self._still_open_and_dbapi_connection_is_valid:
if self._echo:
if self._is_autocommit_isolation():
self._log_info(
"ROLLBACK using DBAPI connection.rollback(), "
"DBAPI should ignore due to autocommit mode"
)
else:
self._log_info("ROLLBACK")
try:
> self.engine.dialect.do_rollback(self.connection)
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:1119:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <sqlalchemy.dialects.sqlite.pysqlite.SQLiteDialect_pysqlite object at 0x7efe20072d60>
dbapi_connection = <sqlalchemy.pool.base._ConnectionFairy object at 0x7efe200bc220>
def do_rollback(self, dbapi_connection):
> dbapi_connection.rollback()
E sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139626483770944 and this is thread id 139626466989632.
.venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py:692: ProgrammingError
The above exception was the direct cause of the following exception:
self = <litestar.middleware._internal.exceptions.middleware.ExceptionHandlerMiddleware object at 0x7efe20090880>
scope = {'_aa_connection_state': {'_sqlalchemy_db_session': <sqlalchemy.orm.session.Session object at 0x7efe2007beb0>}, 'app':...Litestar object at 0x7efe202f0420>, 'client': ('testclient', 50000), 'extensions': {'http.response.template': {}}, ...}
receive = <function TestClientTransport.create_receive.<locals>.receive at 0x7efe20071f70>
send = <function Litestar._wrap_send.<locals>.wrapped_send at 0x7efe10fc0280>
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
"""ASGI-callable.
Args:
scope: The ASGI connection scope.
receive: The ASGI receive function.
send: The ASGI send function.
Returns:
None
"""
scope_state = ScopeState.from_scope(scope)
async def capture_response_started(event: Message) -> None:
if event["type"] == "http.response.start":
scope_state.response_started = True
await send(event)
try:
> await self.app(scope, receive, capture_response_started)
litestar/middleware/_internal/exceptions/middleware.py:158:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
litestar/_asgi/asgi_router.py:99: in __call__
await asgi_app(scope, receive, send)
litestar/routes/http.py:84: in handle
await response(scope, receive, send)
litestar/response/base.py:194: in __call__
await self.start_response(send=send)
litestar/response/base.py:165: in start_response
await send(event)
litestar/middleware/_internal/exceptions/middleware.py:155: in capture_response_started
await send(event)
litestar/app.py:864: in wrapped_send
await hook(message, scope)
litestar/concurrency.py:62: in sync_to_thread
return await _run_sync_asyncio(fn, *args, **kwargs)
litestar/concurrency.py:38: in _run_sync_asyncio
return await asyncio.get_running_loop().run_in_executor(get_asyncio_executor(), bound_fn) # pyright: ignore
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/concurrent/futures/thread.py:57: in run
result = self.fn(*self.args, **self.kwargs)
.venv/lib/python3.8/site-packages/advanced_alchemy/extensions/litestar/plugins/init/config/sync.py:52: in default_before_send_handler
session.close()
.venv/lib/python3.8/site-packages/sqlalchemy/orm/session.py:2468: in close
self._close_impl(invalidate=False)
.venv/lib/python3.8/site-packages/sqlalchemy/orm/session.py:2537: in _close_impl
transaction.close(invalidate)
.venv/lib/python3.8/site-packages/sqlalchemy/orm/state_changes.py:139: in _go
ret_value = fn(self, *arg, **kw)
.venv/lib/python3.8/site-packages/sqlalchemy/orm/session.py:1362: in close
transaction.close()
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2577: in close
self._do_close()
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2715: in _do_close
self._close_impl()
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2701: in _close_impl
self._connection_rollback_impl()
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2693: in _connection_rollback_impl
self.connection._rollback_impl()
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:1121: in _rollback_impl
self._handle_dbapi_exception(e, None, None, None, None)
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2344: in _handle_dbapi_exception
raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
.venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py:1119: in _rollback_impl
self.engine.dialect.do_rollback(self.connection)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <sqlalchemy.dialects.sqlite.pysqlite.SQLiteDialect_pysqlite object at 0x7efe20072d60>
dbapi_connection = <sqlalchemy.pool.base._ConnectionFairy object at 0x7efe200bc220>
def do_rollback(self, dbapi_connection):
> dbapi_connection.rollback()
E sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139626483770944 and this is thread id 139626466989632.
E (Background on this error at: https://sqlalche.me/e/20/f405)
.venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py:692: ProgrammingError
The above exception was the direct cause of the following exception:
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7efe200fda30>
def test_sync_app(monkeypatch: MonkeyPatch) -> None:
from docs.examples.plugins.sqlalchemy_init_plugin import sqlalchemy_sync
monkeypatch.setattr(sqlalchemy_sync.sqlalchemy_config, "connection_string", "sqlite://")
with TestClient(app=sqlalchemy_sync.app) as client:
> res = client.get("/sqlalchemy-app")
tests/examples/test_plugins/test_sqlalchemy_init_plugin.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
litestar/testing/client/sync_client.py:193: in get
return Client.get(
.venv/lib/python3.8/site-packages/httpx/_client.py:1045: in get
return self.request(
litestar/testing/client/sync_client.py:149: in request
return Client.request(
.venv/lib/python3.8/site-packages/httpx/_client.py:821: in request
return self.send(request, auth=auth, follow_redirects=follow_redirects)
.venv/lib/python3.8/site-packages/httpx/_client.py:908: in send
response = self._send_handling_auth(
.venv/lib/python3.8/site-packages/httpx/_client.py:936: in _send_handling_auth
response = self._send_handling_redirects(
.venv/lib/python3.8/site-packages/httpx/_client.py:973: in _send_handling_redirects
response = self._send_single_request(request)
.venv/lib/python3.8/site-packages/httpx/_client.py:1009: in _send_single_request
response = transport.handle_request(request)
litestar/testing/transport.py:173: in handle_request
raise exc
litestar/testing/transport.py:165: in handle_request
portal.call(
.venv/lib/python3.8/site-packages/anyio/from_thread.py:288: in call
return cast(T_Retval, self.start_task_soon(func, *args).result())
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/concurrent/futures/_base.py:444: in result
return self.__get_result()
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/concurrent/futures/_base.py:389: in __get_result
raise self._exception
.venv/lib/python3.8/site-packages/anyio/from_thread.py:217: in _call_func
retval = await retval_or_awaitable
litestar/app.py:591: in __call__
await self.asgi_handler(scope, receive, self._wrap_send(send=send, scope=scope)) # type: ignore[arg-type]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <litestar.middleware._internal.exceptions.middleware.ExceptionHandlerMiddleware object at 0x7efe20090880>
scope = {'_aa_connection_state': {'_sqlalchemy_db_session': <sqlalchemy.orm.session.Session object at 0x7efe2007beb0>}, 'app':...Litestar object at 0x7efe202f0420>, 'client': ('testclient', 50000), 'extensions': {'http.response.template': {}}, ...}
receive = <function TestClientTransport.create_receive.<locals>.receive at 0x7efe20071f70>
send = <function Litestar._wrap_send.<locals>.wrapped_send at 0x7efe10fc0280>
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
"""ASGI-callable.
Args:
scope: The ASGI connection scope.
receive: The ASGI receive function.
send: The ASGI send function.
Returns:
None
"""
scope_state = ScopeState.from_scope(scope)
async def capture_response_started(event: Message) -> None:
if event["type"] == "http.response.start":
scope_state.response_started = True
await send(event)
try:
await self.app(scope, receive, capture_response_started)
except Exception as e:
if scope_state.response_started:
> raise LitestarException("Exception caught after response started") from e
E litestar.exceptions.base_exceptions.LitestarException: Exception caught after response started
litestar/middleware/_internal/exceptions/middleware.py:161: LitestarException
------------------------------ Captured log call -------------------------------
ERROR sqlalchemy.pool.impl.SingletonThreadPool:base.py:381 Exception closing connection <sqlite3.Connection object at 0x7efe20890e40>
Traceback (most recent call last):
File "/home/runner/work/litestar/litestar/.venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 379, in _close_connection
self._dialect.do_close(connection)
File "/home/runner/work/litestar/litestar/.venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 701, in do_close
dbapi_connection.close()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 139626483770944 and this is thread id 139626584458816.
No response
# Your MCVE code here
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"
No response
PR into main
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too