FastAPI-(psycopg2.OperationalError)服务器意外关闭了连接

我有一个使用 FastAPI 和 SQLAlchemy 构建的 Web 应用程序,它在本地使用 Docker 运行正常,但在带有托管 Postgres DB 的 DigitalOcean 上,db 查询失败并出现错误:

(psycopg2.OperationalError) 服务器意外关闭了连接nt这可能意味着服务器在处理请求之前或处理请求时异常终止nt。nn(此错误的背景:http ://sqlalche.me/e /14/e3q8 )"}

我之前在使用 Flask 时遇到过这个错误,问题是我必须设置引擎选项pool_pre_ping=True并将我的 cluster/droplet IP 添加到数据库的可信来源。但是看起来对于 FastAPI 这还不够。我还能做些什么来成功执行查询?

背景

  • 蟒蛇 3.9
  • DigitalOcean 托管 Postgres 13
  • psycopg==2.8.6 但也尝试了 2.8.5(100% 在与 Flask 类似的情况下对我有用)和 2.7.4 以防万一
  • 我已经pool_pre_ping=True设置
    • 我检查过它确实True在使用请求之前设置为正确session.get_bind().pool._pre_ping,它实际上是True
  • 我检查了我的集群节点的 IP 是否在数据库可信来源中
  • 我使用一名uvicorn.workers.UvicornH11Worker工人使用 gunicorn 运行该应用程序
  • 我使用中间件访问 FastAPI enpoints 中的 db 会话,如下所示:
class DBMiddleware:
    def __init__(self, app, sqlalchemy_uri):
        self.app = app
        self.sqlalchemy_uri = sqlalchemy_uri
        self.engine = None

    async def __call__(self, scope: Scope, receive: Receive, send: Send):
        if scope['type'] not in ['http', 'websocket']:
            await self.app(scope, receive, send)
            return

        if not self.engine:
            self.engine = create_engine(self.sqlalchemy_uri, pool_pre_ping=True, pool_recycle=3600)

        session = Session(autoflush=False, autocommit=False, bind=self.engine)
        scope['db'] = session
        await self.app(scope, receive, send)
        session.close()


def get_db(request: Request):
    return request.scope.get('db')

...

@app.on_event('startup')
async def startup():
    ...
    app.add_middleware(DBMiddleware, sqlalchemy_uri=config.SQLALCHEMY_DATABASE_URI)

@router.post('/endpoint')
async def endpoint(db: Session = Depends(get_db)):
    ...
  • 此外,我尝试将全局定义的引擎与会话上下文一起使用(只是为了检查),但仍然具有相同的行为,因此看起来中间件不是问题
  • Postgres 方面没有有用的日志
  • 我还尝试将我的应用程序查询更改为以防db.execute('SELECT 1')万一出现一些奇怪的超时或其他事情 - 仍然相同
  • 我读了很多关于 psycopg2 的类似问题,而我可以找到的关于 FastAPI 的文章很少,例如这个和那个,当然还有官方文档。

毕竟尝试了问题仍然存在。我不太了解asyncPython,所以我怀疑问题可能出在连接的共享方式或其他方面(但我目前只使用一名工人)。

更新

我试图切换到asyncpg(文档:https : //docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html)。也可以在本地运行,但在 DigitalOcean 上查询挂起,我收到以下错误:

[Errno 104] Connection reset by peer

看起来原因是一样的,但是 asyncpg 的错误看起来不同。

还尝试在 DigitalOcean 上创建一个连接池并连接到它 - 仍然是同样的错误。

以上是FastAPI-(psycopg2.OperationalError)服务器意外关闭了连接的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>