如何将MongoDB ObjectId追加到Python类对象并完成序列化?
问题:MongoDB ObjectId列表序列化Python类对象失败
我尝试将从MongoDB查询得到的ObjectId列表result1添加到自定义的Transaction类对象中,使用json_util序列化但未成功,运行代码时抛出TypeError。
原代码
import json import pyodbc import pandas as pd import os from bson import json_util from pymongo import MongoClient class Medicine: def __init__(self, sku, name, diagnosis): self.sku = sku self.name = name self.diagnosis = diagnosis def jsonable(self): return self.__dict__ class Transaction: def __init__(self, custId, bill_no, parent_tx_id, med): self.custId = custId self.bill_no = bill_no self.parent_txxxx_id = parent_tx_id self.med = med def jsonable(self): return self.__dict__ class Diagnosis: def __init__(self, name): self.name = name def jsonable(self): return self.__dict__ def ComplexHandler(Obj): if hasattr(Obj, 'jsonable'): return Obj.jsonable() else: raise TypeError client = MongoClient("mongodb+srv://root:xyz@abcmongodb.net/?retryWrites=true&w=majority") # Select the database and collection db = client["test"] collection = db["collection1"] # Run the query and extract the _id values from the documents result1 = [doc["_id"] for doc in collection.find({}, {"_id": 1})] # Print the results print(result1) #Sample Output: [ObjectId('6409b51df917b0440431c0ba'), ObjectId('6409b51df917b0440431c0bb')] diag = Diagnosis("CBT") med = Medicine("SKU01", "Dolo", diag) transaction = Transaction("adsf", "bu_bill", result1, med) jsonTran = json.dumps(transaction, default=ComplexHandler) print(jsonTran)
报错信息
File "x.py", line 55, in <module> jsonTran = json.dumps(transaction, default=ComplexHandler) File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps return cls( File "/usr/lib/python3.8/json/encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode return _iterencode(o, 0) File "x.py", line 39, in ComplexHandler raise TypeError TypeError
预期输出
{"custId": "adsf", "bill_no": "123", "parent_txxxx_id": [ObjectId('6409b51df917b0440431c0ba'), ObjectId('6409b51df917b0440431c0bb')], "med": {"sku": "SKU01", "name": "Dolo", "diagnosis": {"name": "CBT"}}}
解决方案
错误原因
自定义的ComplexHandler仅处理了带有jsonable方法的自定义类对象,但MongoDB的ObjectId并没有这个方法。当序列化Transaction对象的parent_txxxx_id字段(即ObjectId列表)时,列表中的每个ObjectId都会触发ComplexHandler抛出TypeError。
解决方法一:扩展ComplexHandler处理ObjectId
修改ComplexHandler,加入对ObjectId的判断,使用json_util或直接转字符串来序列化:
from bson import ObjectId, json_util def ComplexHandler(Obj): if hasattr(Obj, 'jsonable'): return Obj.jsonable() elif isinstance(Obj, ObjectId): # 若要保留MongoDB标准的ObjectId JSON格式,用以下代码 return json_util.loads(json_util.dumps(Obj)) # 若仅需要纯字符串ID,替换为 return str(Obj) else: raise TypeError
解决方法二:直接用json_util序列化字典
利用自定义类的jsonable方法先将对象转成字典,再用json_util.dumps序列化(json_util原生支持ObjectId处理):
# 替换原有的json.dumps代码 tran_dict = transaction.jsonable() jsonTran = json_util.dumps(tran_dict) print(jsonTran)
这种方法更简洁,无需修改ComplexHandler,直接借助json_util对MongoDB类型的原生支持完成序列化。
内容的提问来源于stack exchange,提问作者user1720827
相关产品推荐
相关产品推荐

