You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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} })

额外优化建议

  1. 强制userId参数必填,避免空值:
from fastapi import Query

async def addPost(post: postingModel.Posting = Body(...), userId: str = Query(..., description="目标用户ID")):
  1. 校验更新结果,确保操作成功:
if update_result.modified_count == 0:
    raise HTTPException(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        detail="Failed to add posting to user document"
    )
  1. 确保接口返回符合响应模型的内容:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:40:38