【问题标题】:Insert Nested Objects into mongodb in python3 (Nested object is a class Instance)在python3中将嵌套对象插入mongodb(嵌套对象是一个类实例)
【发布时间】:2019-09-17 05:25:06
【问题描述】:

我有一个这样的嵌套结构:


class Student(object):

    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

class Address(object):

    def __init__(self, street, pcode, another_obj):
        self.street = street
        self.postal_code = pcode
        self.another_obj = another_obj

class AnotherObject(object):

    def __init__(self):
        self.someattr = 'some_init_value'


# Now i amm going to save data like this
another_obj = AnotherObject()
address = Address('xyz', 'xyz', another_obj)
obj = Student('abc', 32, address)

对象obj 是一个类的实例。我正在做collection.insert_one(obj)。通常,我会执行 obj.dict 来获取与 pymongo 兼容的类实例的“dict”,但它也不会将嵌套对象转换为 dict。 这里的问题是“地址”和“some_other_object”也是一些其他类实例,这会导致 bson.errors.InvalidDocument 插入时出现异常。

有没有办法将嵌套类实例/文档(地址和 some_other_object)转换为 dict 或 mongodb 可接受的任何其他类型。

我用于mongodb通信的包是pymongo v3.9.0。

错误为 TypeError:

document 必须是 dict、bson.son.SON 的实例, bson.raw_bson.RawBSONDocument,或继承自的类型 集合.MutableMapping

【问题讨论】:

标签: python mongodb


【解决方案1】:

在你的类中添加一些 to_dict() 方法:

from pymongo import MongoClient


class Student(object):

    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

    def to_dict(self) -> dict:
        record = {
            "name": self.name,
            "age": self.age,
            "address": self.address.to_dict() if self.address is not None else None
        }
        return record


class Address(object):

    def __init__(self, street, pcode, another_obj):
        self.street = street
        self.postal_code = pcode
        self.another_obj = another_obj

    def to_dict(self) -> dict:
        record = {
            "street": self.street,
            "postal_code": self.postal_code,
            "another_obj": self.another_obj.to_dict() if self.another_obj is not None else None
        }
        return record


class AnotherObject(object):

    def __init__(self):
        self.someattr = 'some_init_value'

    def to_dict(self) -> dict:
        record = {
            "someattr": self.someattr
        }
        return record


# Now i amm going to save data like this
another_obj = AnotherObject()
address = Address('xyz', 'xyz', another_obj)
obj = Student('abc', 32, address)
db = MongoClient()['yourdatabase']
db.collection.insert_one(obj.to_dict())
print(db.collection.find_one({}))

【讨论】:

  • 如果 Address 类中的“self.another_obj”是一个对象列表,我是否需要调用 to_dict() 直到 self.another_obj 的长度?由于我要处理大量数据,这会不会效率低下?
  • 请阅读此stackoverflow.com/help/someone-answers。如果您有其他具体问题,请提出单独的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
  • 2016-06-25
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多