必须全局复用AsyncIOMotorClient,不可在Depends中每次新建;应于startup时初始化并挂载到app.state,依赖项仅返回database实例,避免连接泄漏与文件描述符耗尽。

直接用 Depends + 异步连接池管理器,就能把 MongoDB 连接从路由里彻底剥离出来,避免每个接口都手动 connect/close,也防止连接泄漏或复用混乱。
为什么不能直接在依赖函数里 new MongoClient?
因为 MotorClient(或 AsyncIOMotorClient)是长生命周期对象,必须全局复用;每次调用依赖函数都新建一个客户端,会快速耗尽系统文件描述符,且无法共享连接池。FastAPI 的依赖注入默认每次请求都执行依赖函数 —— 这正是最容易踩的坑。
- 错误写法:
def get_db(): return AsyncIOMotorClient("mongodb://...")→ 每次请求新建 client - 正确思路:client 实例只创建一次,依赖函数只返回已初始化的
database或collection - 关键点:用模块级变量或
lru_cache保证单例,再通过依赖项封装获取逻辑
如何安全地初始化并复用 AsyncIOMotorClient?
推荐在应用启动时完成 client 初始化,并挂载到 app.state 上。这样既清晰可控,又和 FastAPI 生命周期对齐,还能配合 on_event("startup") 做健康检查。
- 在
main.py或独立db.py中定义初始化函数:async def connect_to_mongo(): app.state.mongodb = AsyncIOMotorClient(...) - 在
startup事件中调用它,确保服务就绪前 client 已 ready - 关闭时显式调用
app.state.mongodb.close(),避免连接残留 - 不依赖
Depends来做 client 创建,只用它来“取”数据库实例
依赖项该返回 database 还是 collection?
返回 database 更通用。collection 是 database 的子资源,具体哪个 collection 应由业务逻辑决定,而不是在依赖层硬编码。强行返回 collection 会导致依赖粒度太细、难以测试、复用性差。
创建 Flask + Vue.js 全栈项目,采用单端口架构、uv 依赖管理、结构化日志和生产级前端设计。当用户要求以下操作时触发:创建新的 Flask+Vue 项目、搭建 Web 应用、构建全栈 Python+Vue 应用、初始化 Flask Web 项目、设置单端口 Flask 前后端项目。触发词:新建项目、创建项目、搭建项目、Flask项目、Vue项目。
- 推荐依赖函数:
async def get_database() -> AsyncIOMotorDatabase: return app.state.mongodb.get_database("myapp") - 路由中使用:
def read_items(db: AsyncIOMotorDatabase = Depends(get_database)) - 需要 collection 时,在路由内部调用
db.get_collection("items"),而非让依赖返回它 - 如果项目有强多租户需求(如按用户分库),才考虑让依赖接收参数动态选库
依赖嵌套时怎么避免循环引用?
常见陷阱是把数据库依赖和业务 service(如 UserRepo)互相引用:service 需要 db,db 依赖又试图 import service。根本解法是严格分层 —— 数据访问层(db)绝对不能依赖上层(service / auth / cache)。
- 把
get_database放在db.py,只 import motor 和 fastapi - 把
UserRepo放在repos/user.py,构造时接收database: AsyncIOMotorDatabase作为参数,不 import db 模块 - 路由中组合:
repo = UserRepo(db=await get_database()),或更进一步用另一个依赖封装 repo 构造逻辑 - 一旦出现
ImportError: cannot import name 'xxx' from partially initialized module,基本就是这个原因
最易被忽略的一点:MongoDB 连接字符串里的 maxPoolSize 和 minPoolSize 必须根据 uvicorn worker 数和预期并发量调优,默认值(100/0)在高负载下反而容易成为瓶颈。别只盯着代码结构,连接池配置错了,再干净的依赖注入也救不了性能。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










