You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
Tortoise seems to crash when used with Vercel (and probably any serverless service) + FastAPI.
When using tortoise-orm with FastAPI and Vercel, tortoise cannot manage to fetch the database connection resulting in the following error:
TypeError: 'NoneType' object is not iterable
Traceback (most recent call last):
File "/var/task/vc__handler__python.py", line 315, in vc_handler
response = asgi_cycle(__vc_module.app, body)
File "/var/task/vc__handler__python.py", line 215, in __call__
asyncio.run(self.run_asgi_instance(asgi_instance))
File "/var/lang/lib/python3.12/asyncio/runners.py", line 194, in run
return runner.run(main)
File "/var/lang/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
File "/var/lang/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
return future.result()
File "/var/task/vc__handler__python.py", line 219, in run_asgi_instance
await asgi_instance
File "/var/task/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/var/task/starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "/var/task/starlette/middleware/errors.py", line 186, in __call__
raise exc
File "/var/task/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "/var/task/starlette/middleware/cors.py", line 85, in __call__
await self.app(scope, receive, send)
File "/var/task/starlette/middleware/exceptions.py", line 65, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/var/task/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/var/task/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/var/task/starlette/routing.py", line 756, in __call__
await self.middleware_stack(scope, receive, send)
File "/var/task/starlette/routing.py", line 776, in app
await route.handle(scope, receive, send)
File "/var/task/starlette/routing.py", line 297, in handle
await self.app(scope, receive, send)
File "/var/task/starlette/routing.py", line 77, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/var/task/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/var/task/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/var/task/starlette/routing.py", line 72, in app
response = await func(request)
File "/var/task/fastapi/routing.py", line 278, in app
raw_response = await run_endpoint_function(
File "/var/task/fastapi/routing.py", line 191, in run_endpoint_function
return await dependant.call(**values)
File "/var/task/Manager/main.py", line 48, in some_example
await Video.all() # KO
File "/var/task/tortoise/models.py", line 1262, in all
return cls._db_queryset(using_db)
File "/var/task/tortoise/models.py", line 1063, in _db_queryset
db = using_db or cls._choose_db(for_write)
File "/var/task/tortoise/models.py", line 1011, in _choose_db
db = router.db_for_read(cls)
File "/var/task/tortoise/router.py", line 36, in db_for_read
return self._db_route(model, "db_for_read")
File "/var/task/tortoise/router.py", line 31, in _db_route
return connections.get(self._router_func(model, action))
File "/var/task/tortoise/router.py", line 18, in _router_func
for r in self._routers:
To Reproduce
Here is the code-snippet to reproduce it:
# app/main.pyfromfastapiimportFastAPIfromtortoiseimportTortoisefromcontextlibimportasynccontextmanagerfromtortoise.contrib.fastapiimportRegisterTortoisefromtortoiseimportmodels, fields# NOTE: this must be defined in# a different file and then importedclassSomeTable(models.Model):
id=fields.IntField(pk=True)
@asynccontextmanagerasyncdeflifespan(app: FastAPI):
asyncwithRegisterTortoise(
app=app,
config=YOUR_CONFIG_HERE,
generate_schemas=True,
add_exception_handlers=True,
):
yieldawaitTortoise.close_connections()
app=FastAPI(lifespan=lifespan)
@app.get("/some-example")asyncdefsome_example():
awaitSomeTable.all() # TypeError: 'NoneType' object is not iterablereturn"some expected response"if__name__=="__main__":
importuvicornuvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
Obviously, in order to reproduce the error one also needs to deploy it on Vercel :)
Expected behavior
I would expect tortoise to use previously initialized connection to return every elements of SomeTable.
Additional context
Note that in order to debug I also tried the following, which also results in a crash. However this time it crashs at the second call to the database as it tried to close an event loop that no-longer exists, resulting in a RuntimeError('Event loop is closed') error.
# app/main.pyfromfastapiimportFastAPIfromtortoiseimportTortoisefromcontextlibimportasynccontextmanagerfromtortoise.contrib.fastapiimportRegisterTortoisefromtortoiseimportmodels, fields# NOTE: this must be defined in# a different file and then importedclassSomeTable(models.Model):
id=fields.IntField(pk=True)
asyncdefinit_db():
awaitTortoise.init(config=YOUR_CONFIG_HERE)
awaitTortoise.generate_schemas()
app=FastAPI()
@app.get("/some-example")asyncdefsome_example():
awaitinit_db() # First call works# second calls fail with `raise RuntimeError('Event loop is closed')``awaitSomeTable.all()
return"some expected response"if__name__=="__main__":
importuvicornuvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
The text was updated successfully, but these errors were encountered:
Update: I found this temporary fix, however I'll obviously need to find a better option :D
@app.middleware("http")asyncdefadd_process_time_header(request: Request, call_next):
awaitinit_db() # already in the previous snippetresponse=awaitcall_next(request)
awaitTortoise.close_connections() # Now also close the session after each callreturnresponse
Describe the bug
Tortoise seems to crash when used with Vercel (and probably any serverless service) + FastAPI.
When using
tortoise-orm
with FastAPI and Vercel, tortoise cannot manage to fetch the database connection resulting in the following error:To Reproduce
Here is the code-snippet to reproduce it:
Obviously, in order to reproduce the error one also needs to deploy it on Vercel :)
Expected behavior
I would expect tortoise to use previously initialized connection to return every elements of
SomeTable
.Additional context
Note that in order to debug I also tried the following, which also results in a crash. However this time it crashs at the second call to the database as it tried to close an event loop that no-longer exists, resulting in a
RuntimeError('Event loop is closed')
error.The text was updated successfully, but these errors were encountered: