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

使用FastAPI从MongoDB获取数据时遭遇500内部服务器错误求助

问题描述

我编写了一个用于从MongoDB获取数据的FastAPI接口,当尝试查询集合中的所有交易数据时,遇到了500内部服务器错误。已确认MongoDB连接正常、集合存有数据,FastAPI单独运行无异常,仅查询集合时出错。

代码示例

from fastapi import FastAPI, HTTPException
from pymongo import MongoClient 
from bson import json_util
import json

app = FastAPI()

# MongoDB connection details
mongo_url = "mongodb://localhost:27017/"  
client = MongoClient(mongo_url)
db = client.banking  
collection = db.transaction_data 

@app.get("/")
async def root():
    return {"message": "Hello World"}

# all transactions
@app.get("/transactions")
async def get_transactions():
    try:
        transactions = collection.find()
        
        # Transform the cursor to a list of dictionaries
        transaction_list = [transaction for transaction in transactions]

        # Return the list of dictionaries
        return transaction_list
        
    except:
        raise HTTPException(status_code=404, detail="Transactions not found")

错误现象

Swagger文档返回500内部服务器错误,提示"Internal Server Error"


解决方法

1. 问题根源

MongoDB查询返回的文档包含ObjectId这类BSON专属类型,FastAPI默认的JSON序列化器无法处理该类型,导致返回响应时触发序列化失败,抛出500错误。另外你的空except:语句没有捕获到这个返回阶段的异常(异常发生在return序列化时,而非查询循环过程中),还错误地返回了404状态码(这是资源不存在的状态,不符合当前服务器内部错误的场景)。

2. 具体修复方案

方案一:利用json_util处理BSON序列化

使用bson.json_util工具完成BSON到JSON的转换,再转为Python字典返回:

@app.get("/transactions")
async def get_transactions():
    try:
        transactions = collection.find()
        # 用json_util处理BSON类型,再解析为Python字典列表
        transaction_list = json.loads(json_util.dumps(transactions))
        return transaction_list
    except Exception as e:
        # 打印错误信息便于调试
        print(f"Debug Error: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Server error: {str(e)}")

方案二:手动转换ObjectId为字符串

遍历查询结果时,手动将_id字段转换为字符串类型:

@app.get("/transactions")
async def get_transactions():
    try:
        transactions = collection.find()
        transaction_list = []
        for transaction in transactions:
            # 将MongoDB的ObjectId转为普通字符串
            transaction["_id"] = str(transaction["_id"])
            transaction_list.append(transaction)
        return transaction_list
    except Exception as e:
        print(f"Debug Error: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Server error: {str(e)}")

3. 额外优化建议

  • 避免使用空的except:,明确捕获Exception并打印错误信息,方便快速定位问题
  • 状态码要匹配场景:服务器内部错误返回500,404仅用于确实找不到资源的情况

内容的提问来源于stack exchange,提问作者Russel Osiemo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:42:48