Describe the bug
With Tortoise ORM 1.1.7, tortoise.contrib.blacksheep.register_tortoise sets up
the ORM in the app's on_start (ASGI lifespan) hook, but any DB query inside a
request handler raises:
RuntimeError: No TortoiseContext is currently active. Use 'async with
TortoiseContext() as ctx:' to create one, or call Tortoise.init() for global state.
The lifespan hook runs in a different asyncio task than request handlers. Since
1.x stores connection state in a contextvars.ContextVar (_current_context),
the context entered during startup is not visible in handler tasks, and no global
fallback is set — so require_context() fails.
The FastAPI integration does not have this problem because
RegisterTortoise defaults _enable_global_fallback=True
(tortoise/contrib/fastapi/__init__.py, _enable_global_fallback: bool = True).
The blacksheep integration calls Tortoise.init(...) without that flag, so
the global fallback context described in tortoise/context.py (lines ~48-52) is
never enabled.
To Reproduce
import asyncio
from tortoise import Tortoise
CONFIG = {
"connections": {"default": "sqlite://:memory:"},
"apps": {"models": {"models": ["__main__"], "default_connection": "default"}},
}
from tortoise import fields, models
class User(models.Model):
id = fields.IntField(pk=True)
async def run(enable_fallback: bool) -> str:
async def init_task():
await Tortoise.init(config=CONFIG, _enable_global_fallback=enable_fallback)
await Tortoise.generate_schemas()
await asyncio.create_task(init_task()) # like the lifespan task
async def query_task():
await User.all().count() # like a request handler
return "ok"
try:
return await asyncio.create_task(query_task())
except RuntimeError as exc:
return f"RuntimeError: {exc}"
finally:
await Tortoise.close_connections()
async def main():
print("without:", await run(False))
print("with: ", await run(True))
asyncio.run(main())
Output:
without: RuntimeError: No TortoiseContext is currently active. ...
with: ok
A full repro with an actual BlackSheep app + register_tortoise shows the same
RuntimeError on the first request that touches the DB.
Expected behavior
register_tortoise should make the ORM usable from request handlers out of the
box, the same as the FastAPI integration.
Additional context
Pass _enable_global_fallback=True in the blacksheep integration's
Tortoise.init(...) call (matching contrib.fastapi.RegisterTortoise).
Describe the bug
With Tortoise ORM 1.1.7,
tortoise.contrib.blacksheep.register_tortoisesets upthe ORM in the app's
on_start(ASGI lifespan) hook, but any DB query inside arequest handler raises:
The lifespan hook runs in a different asyncio task than request handlers. Since
1.x stores connection state in a
contextvars.ContextVar(_current_context),the context entered during startup is not visible in handler tasks, and no global
fallback is set — so
require_context()fails.The FastAPI integration does not have this problem because
RegisterTortoisedefaults_enable_global_fallback=True(
tortoise/contrib/fastapi/__init__.py,_enable_global_fallback: bool = True).The blacksheep integration calls
Tortoise.init(...)without that flag, sothe global fallback context described in
tortoise/context.py(lines ~48-52) isnever enabled.
To Reproduce
Output:
A full repro with an actual BlackSheep app +
register_tortoiseshows the sameRuntimeErroron the first request that touches the DB.Expected behavior
register_tortoiseshould make the ORM usable from request handlers out of thebox, the same as the FastAPI integration.
Additional context
Pass
_enable_global_fallback=Truein the blacksheep integration'sTortoise.init(...)call (matchingcontrib.fastapi.RegisterTortoise).