使用fastapi和tortoise-orm==0.19.3。表Server
有大约25,000条记录。
我用端点/servers/
获取所有这些。
@server_router.get("/servers")
async def get_servers():
ret = await ServerPydantic.from_queryset(Server.all())
return ret
没有分页和偏移量,我这样做是为了测试。
还有另一个终点:
@server_router.get("/servers-test/{s}")
async def test(s:int):
print(f"sleeping for {s} seconds")
await asyncio.sleep(s)
return {"test": "test"}
我向端点/server
发出请求,然后快速向端点/servers-test/{s}
发出两个请求:
curl http://127.0.0.1/servers
,这需要一些时间,大约4- 5秒curl http://127.0.0.1/servers-test/5
,就在第一个请求之后curl http://127.0.0.1/servers-test/0
紧接在上一个请求之后
通过查看函数中的print语句,我可以立即判断出最后一个请求根本没有被处理,它被调用/servers
阻塞,直到第一个请求完成。只有这样,其他两个请求才开始运行。
如果我做了
@server_router.get("/servers")
async def get_servers():
asyncio.sleep(30)
print("sleeping done")
ret = await ServerPydantic.from_queryset(Server.all())
return ret
基本上我只是添加了asyncio.sleep(30)
。然后我重复上面提到的步骤。
curl http://127.0.0.1/servers
,这将需要很长时间,因为asyncio.sleep(30)
curl http://127.0.0.1/servers-test/5
,在第一个请求之后,它立即得到服务curl http://127.0.0.1/servers-test/0
在上一个请求之后,它立即得到服务
如果我在30秒后发出请求,那么请求会再次被阻止。所以很明显,Server.all()
会阻止I/O。这是意料之外的。我做错了什么吗?我在Google和Tortoise-orm Github上搜索了问题,但没有找到相关信息。
更新:我试过使用sqlalchemy,同样的事情发生了。所以它不是Tortoise-orm相关的I geuess。
我试过这个:
# some sessions and schemas setup are not shown here.
@app.get("/serversv2", response_model=ServerList)
async def get_all_servers(session: AsyncSession = Depends(get_session)):
result = await session.execute(select(Server1))
servers = result.scalars().all()
return {"servers": servers}
它仍然阻止其他请求。
1条答案
按热度按时间waxmsbnn1#
您没有显示
Server
对象是什么-但如果这是一个同步调用,它将阻塞它们。如果你将结果传递给Pydantic中的异步调用,这并不重要:对X1 M1 N1 X的调用将仅在 * X1 M2 N1 X已经返回之后 * 发生。
由于您没有发布所有代码,因此我不能在答案中如此肯定-但也许
Server
对象本身是可迭代的,如果您不对它调用all()
,那么“做正确的事情”?然后您只需将Server对象本身传递给from_queryset
调用(这听起来像是应该做的事情,无论如何-.all()
方法的返回是查询结果本身,而不是查询集)。