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

Flask读取MongoDB导出JSON报错:ObjectId类型无法JSON序列化

解决Flask读取MongoDB时ObjectId无法JSON序列化的问题

问题原因

MongoDB文档中的_id字段(或其他自定义ObjectId字段)属于bson.objectid.ObjectId类型,Python标准JSON序列化器及默认Flask序列化逻辑无法直接识别该类型,因此抛出TypeError: Object of type ObjectId is not JSON serializable错误。

解决方案

方案1:遍历转换ObjectId为字符串

查询数据后直接遍历,将所有ObjectId类型字段转为字符串:

@app.route('/export-json', methods=['GET', 'POST'])
def export_json():
    collection_name = 'movie_info'  
    data = list(db[collection_name].find({}))
    
    # 转换所有文档的_id为字符串
    for doc in data:
        if '_id' in doc:
            doc['_id'] = str(doc['_id'])
        # 若存在其他ObjectId类型字段,按同样方式转换
        # if 'custom_objectid_field' in doc:
        #     doc['custom_objectid_field'] = str(doc['custom_objectid_field'])

    # 写入JSON文件
    with open('data.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)

    return jsonify({'message': 'Data exported to data.json'})

方案2:查询时排除_id字段(无需该字段时使用)

如果导出的JSON不需要_id字段,可在MongoDB查询阶段直接排除:

data = list(db[collection_name].find({}, {'_id': 0}))

方案3:自定义全局JSON编码器(推荐)

创建自定义JSON编码器,让Flask全局支持ObjectId序列化,无需每次手动转换:

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

# 自定义JSON编码器,处理ObjectId类型
class MongoJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, ObjectId):
            return str(obj)
        # 如需支持其他BSON类型(如Datetime),可在此扩展逻辑
        return super().default(obj)

app = Flask(__name__)
# 将自定义编码器注册到Flask
app.json_encoder = MongoJSONEncoder

mongo_client = MongoClient('mongodb://localhost:27017/')
db = mongo_client['movies_db']

@app.route('/')
def index():
    return 'Welcome to my Project!'

@app.route('/export-json', methods=['GET', 'POST'])
def export_json():
    collection_name = 'movie_info'  
    data = list(db[collection_name].find({}))

    # 写入文件时指定自定义编码器
    with open('data.json', 'w') as json_file:
        json.dump(data, json_file, indent=4, cls=MongoJSONEncoder)

    return jsonify({'message': 'Data exported to data.json'})

if __name__ == '__main__':
    app.run()

关于之前尝试失效的说明

你之前使用jsonify(data).get_json()获取序列化后的字典,理论上jsonify会自动处理ObjectId,但如果Flask版本较低,或文档中存在其他未被处理的ObjectId字段,仍会导致后续json.dump失败。上述方案从根源上覆盖了所有可能场景,确保序列化正常。

内容的提问来源于stack exchange,提问作者Aadhithya Prakash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:12:16