开启reload=True时Uvicorn连接LMDB数据库报错的解决方法
解决Uvicorn reload模式下LMDB数据库重复打开报错的问题
问题根源
Uvicorn开启reload=True时,会启动两个进程:一个文件监控进程负责监听代码变化,另一个工作进程才是真正运行FastAPI应用的进程。你把LMDB环境创建语句db = lmdb.Environment(...)写在模块顶级(全局范围),导致两个进程都会执行这条语句,而Windows系统下LMDB的文件映射机制不允许同一数据库被多个进程以默认方式打开,直接触发The requested operation cannot be performed on a file with a user-mapped section open错误。
解决方案
把LMDB的初始化逻辑移到FastAPI的启动事件中,只有工作进程会执行这段初始化代码,监控进程不会触发该事件,避免重复打开数据库:
from fastapi import FastAPI import lmdb app = FastAPI() # 先声明全局变量,后续在启动事件中赋值 db = None # 应用启动时初始化LMDB @app.on_event("startup") def init_lmdb(): global db # 替换成你的dbname和dbpath参数 db = lmdb.Environment(dbname, dbpath) # 应用关闭时关闭LMDB连接,避免资源泄漏 @app.on_event("shutdown") def close_lmdb(): if db is not None: db.close() if __name__ == "__main__": import uvicorn uvicorn.run('myprogram:app', host="0.0.0.0", port=8000, log_level="debug", reload=True,)
额外说明
- 不要用
lock=False这类参数绕过错误,这会破坏LMDB的并发安全机制,仅适合极端临时测试场景。 - 生产环境建议关闭
reload,此时模块级初始化不会有问题,但仍推荐用启动事件管理资源,保持代码一致性。
内容的提问来源于stack exchange,提问作者Henry Thornton
相关产品推荐
相关产品推荐

