Reputation: 416
I have a nested structure like this:
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)
The object obj is an instance of a class. I am doing collection.insert_one(obj). Usually, I would do obj.dict to get "dict" of class instance which is compatible with pymongo but it does not convert the nested objects into dict too. The problem here is that the "address" and "some_other_object" are also some other class instances and that causes bson.errors.InvalidDocument Exception while insertion.
Is there a way to convert nested class instances/documents (address & some_other_object) into dict or any other type acceptable to mongodb.
The package I am using for mongodb communication is pymongo v3.9.0.
Error is TypeError:
document must be an instance of dict, bson.son.SON, bson.raw_bson.RawBSONDocument, or a type that inherits from collections.MutableMapping
Upvotes: 2
Views: 1369
Reputation: 8814
Add in some to_dict() methods to your classes:
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({}))
Upvotes: 1