Psycopg / asyncio设置偶数循环策略



祝你一切安好!

我有一个问题,Psycopg模块允许与PostgreSQL数据库交互。

当我启动我的HTTP服务器(我使用FastAPI和Uvicorn)正常,我发送请求到我的服务器,我有这个错误:

error connecting in 'pool-1': Psycopg cannot use the 'ProactorEventLoop' to run in async mode. Please use a compatible event loop, for instance by setting 'asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())'

我已经做了错误解决方案所建议的,即将事件循环策略设置为WindowsSelectorEventLoopPolicy,我做到了。

import asyncio
from asyncio import WindowsSelectorEventLoopPolicy

asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())

我把这行放在我的主文件中(这是我的应用程序的中心文件)但是仍然没有,当我向服务器发送请求时,我仍然有相同的错误。

但奇怪的是,当我用--reload选项启动服务器时(根据Uvicorn/FastAPI的文档,该选项用于在修改的情况下自动重新加载文件,但不适合生产),当我发送请求时,我没有错误,一切正常

你能告诉我问题的原因是什么以及如何解决它吗?p。S:这是我如何从Windows Powershell启动HTTP的方法

这是我如何启动我的HTTP服务器正常(不工作)

uvicorn src.main:app --port 2314

下面是我如何使用——reload选项启动HTTP服务器(它工作得很好)

uvicorn src.main:app --port 2314 --reload

Uvicorn默认使用reload选项和Windows时设置WindowsSelectorEventLoopPolicy策略,否则不设置。这就是为什么您面临这种不匹配行为。

改变另一个策略应该是有效的,也许它放错了地方。

import asyncio
import uvicorn
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
async def app(scope, receive, send):
print(asyncio.get_event_loop_policy())
if __name__ == "__main__":
uvicorn.run("main:app", port=8010)

如果我们删除我们设置策略的行,并且我们已经安装了uvloop(如果安装了uvicorn会自动选择uvloop),我们可以看到uvloop策略被打印。

如果没有错,我建议在uvicorn上展开讨论。

免责声明:我是Uvicorn的维护人员。

谢谢!在做了几次测试并再次阅读了uvicorn的文档后。

一切都是我的错

我从终端(在我的例子中是Powershell)的命令行直接启动了uvicorn HTTP服务器(没有--reload选项),我得到了错误。

error connecting in 'pool-1': Psycopg cannot use the 'ProactorEventLoop' to run in async mode. Please use a compatible event loop, for instance by setting 'asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())'

因为这种方式没有读取我在main.py文件中所做的导入,而只是启动服务器而不关心任何事情,因此错误要求我将事件循环策略设置为WindowsSelectorEventLoopPolicy(我已经这样做了),仅仅是因为从未到达定义事件循环策略的导入行。

所以现在不是像这样直接在终端中启动我的uvicorn服务器

uvicorn src.main:app --port 2314

我像这样执行我的python代码

python -m src.main

,我必须像这样修改main.py中的代码

import asyncio
from asyncio import WindowsSelectorEventLoopPolicy
import uvicorn
from fastapi import FastAPI
...
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())

app = FastAPI()
...
if __name__ == '__main__':
uvicorn.run('src.main:app', host="127.0.0.1", port=2314)

它在终端上没有任何问题的原因是通过运行我的HTTP服务器和--reload选项,像这样

uvicorn src.main:app --port 2314 --reload

等于@marcelo-trylesinski说,--reload选项自动将事件循环设置为WindowsSelectorEventLoopPolicy。我希望这可以在文档中通知/提到。

再次感谢@marcelo-trylesinski感谢他的帮助

最新更新