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
相关产品推荐
相关产品推荐

