FastAPI中如何向MongoDB的对象数组插入新对象?
问题:FastAPI+PyMongo无法向MongoDB对象数组插入新对象
已查阅但未解决的资料
- Insert an element into an array of nested model Mongodb with PyMongo on FASTAPI
- Inserting an object inside an array fails
- how to insert an object to array in mongodb database
- MongoDB - Update or Insert object in array
文档结构
- 用户顶级文档:包含
_id、email、name等字段,同时存在一个postings数组,数组元素为Posting对象 - Posting对象:包含自动生成的
_id、timestamp字段,以及title、totalNumOfRoommates等业务字段
请求体格式:
{ "title" : "new posting", "totalNumOfRoommates" : 17 }
尝试的代码
@router.post('/', response_description='Creates a posting for a specified user', response_model=postingModel.Posting) async def addPost(post: postingModel.Posting = Body(...), userId: str = ""): user = await dbConnection.find_one({"_id" : userId}) if user is None: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="User ID was not provided or was wrong, please provide it as a query parameter Example: http://127.0.0.1:8000/api/postings?userId=abcd-1234-efgh-5678", ) post = jsonable_encoder(post) update_result = await dbConnection.update_one({"_id": id}, {"$push" : {"postings" : post} })
问题现象
post的格式符合预期:
{ '_id': '6de685e7-d55f-4412-99e1-adf03f013cdd', 'timestamp': '2022-10-19T16:44:23.190900', 'title': 'new posting', 'totalNumOfRoommates': 17 }
但执行时抛出错误,关键错误信息:
bson.errors.InvalidDocument: cannot encode object: <built-in function id>, of type: <class 'builtin_function_or_method'>
解决方法
错误根源是代码中update_one的查询条件误用了Python内置函数id,而非传入的userId变量。修改查询条件即可解决:
修正核心代码
# 错误代码 update_result = await dbConnection.update_one({"_id": id}, {"$push" : {"postings" : post} }) # 修正后代码 update_result = await dbConnection.update_one({"_id": userId}, {"$push" : {"postings" : post} })
额外优化建议
- 强制
userId参数必填,避免空值:
from fastapi import Query async def addPost(post: postingModel.Posting = Body(...), userId: str = Query(..., description="目标用户ID")):
- 校验更新结果,确保操作成功:
if update_result.modified_count == 0: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to add posting to user document" )
- 确保接口返回符合响应模型的内容:
return post
完整修正代码
from fastapi import Query, HTTPException, status, Body from fastapi.routing import APIRouter import postingModel from your_db_module import dbConnection # 替换为实际的数据库连接模块 router = APIRouter() @router.post('/', response_description='Creates a posting for a specified user', response_model=postingModel.Posting) async def addPost(post: postingModel.Posting = Body(...), userId: str = Query(..., description="目标用户ID")): user = await dbConnection.find_one({"_id" : userId}) if user is None: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="用户ID不存在或未提供,请按示例格式传入:http://127.0.0.1:8000/api/postings?userId=abcd-1234-efgh-5678", ) post = jsonable_encoder(post) update_result = await dbConnection.update_one({"_id": userId}, {"$push" : {"postings" : post} }) if update_result.modified_count == 0: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="添加发布内容失败" ) return post
内容的提问来源于stack exchange,提问作者Ahmet-Salman
相关产品推荐
相关产品推荐

