I have a collection in Mongoengine with long list of fields which contains some documents:
class Component(Document):
name = StringField(unique=True)
title = StringField(required=True)
description = StringField(default='')
# And so on...
Now I want another collection similar to the first collection with some extra stuffs. So I used allow_inheritance
in the first collection for subclassing:
class Component(Document):
name = StringField(unique=True)
title = StringField(required=True)
description = StringField(default='')
# And so on...
meta = {'allow_inheritance': True}
class ChildComponent(Component):
extra_stuff = StringField()
But as the documents mentions, this way all the data will save in the same collection.
So I tried adding abstract
to meta in the parent document, so I can have two separate collections.
class Component(Document):
name = StringField(unique=True)
title = StringField(required=True)
description = StringField(default='')
# And so on...
meta = {'allow_inheritance': True, 'abstract': True}
But now when I try to get the documents from Component
using Component.objects().all()
I get this error:
AttributeError: type object 'Component' has no attribute 'objects'
Should I create a base document and abstract my two collections from it or there's simpler way to solve this issue?
UPDATE
Even if I create a base class and inherit both classes from it:
class BaseComponent(Document):
name = StringField(unique=True)
title = StringField(required=True)
description = StringField(default='')
# And so on...
meta = {'allow_inheritance': True, 'abstract': True}
class Component(BaseComponent):
pass
class ChildComponent(BaseComponent):
extra_stuff = StringField()
When I try Component.objects.all()
, the result will be and empty list.
UPDATE 2
If I add a component
with .save()
I can get that one with Component.objects.all()
. But what about the rest of the documents which are already saved in that collection? How can I restore them?
Since I got no answer, I've found a work around for it. When using abstract
in meta, the child collections get an extra field called _cls
with the collection name as value. So I used pymongo to update existing documents with a _cls
field and value equals to the collection name like this:
db["component"].update_many({}, {"$set": {"_cls": "Component"}}, upsert=False, array_filters=None)
After doing this, now I can get the documents using mongoengine Component.objects().all()
query.