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

如何获取MongoDB数据的JSON数组?解决ObjectID序列化失败问题

解决MongoDB ObjectId无法JSON序列化的问题

我懂你的困扰,ObjectId作为MongoDB默认的文档主键,确实常在API返回数据时出现序列化报错的问题,不过解决方法其实挺简单的,给你几个实用的方案:

方案1:查询时直接将ObjectId转为字符串(最简便)

MongoDB支持在查询阶段通过$toString操作符直接把_id字段转换成字符串,这样返回的文档里_id就是普通字符串,直接用jsonify返回即可:

@app.route('/api/getUsers', methods=['GET'])
def getUsers():
    # 使用投影操作将_id转为字符串
    allUsers_cursor = userCollection.find({}, {"_id": {"$toString": "$_id"}})
    allUsers = list(allUsers_cursor)
    return jsonify(allUsers), 200

这个方法的好处是不需要额外的Python代码处理,直接从数据库拿到可序列化的数据。

方案2:遍历文档手动转换ObjectId

如果需要保留更多原始数据的处理灵活性,可以在把游标转为列表时,手动将每个文档的_id转为字符串:

@app.route('/api/getUsers', methods=['GET'])
def getUsers():
    allUsers_cursor = userCollection.find({})
    allUsers = []
    for user in allUsers_cursor:
        # 将ObjectId转为字符串
        user['_id'] = str(user['_id'])
        allUsers.append(user)
    return jsonify(allUsers), 200

这种方式适合需要对文档做其他自定义处理的场景。

方案3:全局注册自定义JSON编码器(一劳永逸)

如果你在项目里经常需要返回MongoDB文档,可以自定义一个JSON编码器,让Flask自动处理ObjectId的序列化:

from bson.objectid import ObjectId
import json
from flask import Flask, jsonify

app = Flask(__name__)

# 自定义JSON编码器
class MongoJSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, ObjectId):
            return str(o)
        # 其他需要序列化的类型也可以在这里扩展
        return super().default(o)

# 注册到Flask应用
app.json_encoder = MongoJSONEncoder

@app.route('/api/getUsers', methods=['GET'])
def getUsers():
    allUsers_cursor = userCollection.find({})
    allUsers = list(allUsers_cursor)
    # 现在直接返回即可,编码器会自动处理ObjectId
    return jsonify(allUsers), 200

这个方案只需要配置一次,之后所有用jsonify返回的MongoDB文档都会自动处理ObjectId,非常适合大型项目。

为什么会报错?

MongoDB的每个文档默认会生成一个_id字段,类型是ObjectId(属于bson库的自定义类型),而Python标准的JSON序列化器不知道如何处理这种非内置类型,所以会抛出"ObjectId is not JSON serializable"的错误——本质就是告诉我们:这个类型我不认识,你得告诉我怎么转成JSON支持的格式(比如字符串)。

内容的提问来源于stack exchange,提问作者Ryan T. J.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:37:55