FastAPI操作MongoDB时出现422 Unprocessable Entity错误排查
MongoDB更新操作失败排查求助
我尝试对MongoDB数据库中的数据执行简单更新操作,但始终无法成功,完全找不到问题所在,求帮助。
代码片段
models.py
class Text(BaseModel): id: str = Field(default_factory=uuid.uuid4, alias="_id") text: str = Field(...) gold: bool = Field(...) annotations: int = Field(...) class Config: allow_population_by_field_name = True schema_extra = { 'example': { '_id': '066de609-b04a-4b30-b46c-32537c7f1f6e', 'text': 'The first mission to the moon happend in 1969...', 'gold': 'False', 'annotations': '1' } } class AnnotationCountUpdate(BaseModel): annotations: int = Field(...) class Config: schema_extra = { "example": { "annotations": 1 } }
routes.py
@router.put("/{text_id}", response_description="Update text annotation count", response_model=Text) def update_count(text_id: str, request: Request, update: AnnotationCountUpdate = Body(...)): update = {k: v for k, v in update.dict().items() if v is not None} if len(update) >= 1: update_result = request.app.data.update_one( {"_id": text_id}, {"set": update} ) if update_result.modified_count == 0: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Text with ID {text_id} not found") if (existing_text := request.app.data.find_one({"_id": text_id})) is not None: return existing_text raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Text with ID {text_id} not found")
数据库与响应情况
- 数据库中文档包含
_id(字符串类型)、text、gold(布尔值)、annotations(数值类型)字段 - 请求返回404错误,提示
Text with ID {text_id} not found,但对应ID的文档实际存在于数据库中
问题原因及解决方法
更新操作符错误
代码中使用{"set": update}是错误的,MongoDB的更新操作符必须以$开头,正确写法应为{"$set": update}。这个错误会导致更新操作完全不生效,进而触发modified_count == 0的判断,抛出不必要的404错误。潜在的ID类型不匹配问题
检查数据库中_id的类型:如果数据库里_id是ObjectId类型,而传入的text_id是字符串,查询和更新都会匹配失败。需要将text_id转换为ObjectId:from bson.objectid import ObjectId # 查询和更新时替换为: {"_id": ObjectId(text_id)}冗余的404判断逻辑
当更新值与文档原有值相同时,modified_count也会为0,此时不应该直接判定文档不存在。建议调整逻辑,先检查文档是否存在,再执行更新:if len(update) >= 1: # 先验证文档存在性 existing = request.app.data.find_one({"_id": text_id}) if not existing: raise HTTPException(status_code=404, detail=f"Text with ID {text_id} not found") # 执行正确的更新操作 update_result = request.app.data.update_one({"_id": text_id}, {"$set": update})
内容的提问来源于stack exchange,提问作者Dim
相关产品推荐
相关产品推荐

