在 Mongoengine 的单独集合中子类化文档

Subclassing document in separate collections in Mongoengine

我在 Mongoengine 中有一个集合,其中包含一长串字段,其中包含一些文档:

class Component(Document):
    name = StringField(unique=True)
    title = StringField(required=True)
    description = StringField(default='')
    # And so on...

现在我想要另一个类似于第一个集合的集合,但要添加一些额外的东西。所以我在 subclassing:

的第一个集合中使用了 allow_inheritance
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()

但是正如 documents 提到的,这样所有的数据都会保存在同一个集合中。

所以我尝试将 abstract 添加到父文档的元数据中,这样我就可以有两个单独的集合。

class Component(Document):
    name = StringField(unique=True)
    title = StringField(required=True)
    description = StringField(default='')
    # And so on...
    meta = {'allow_inheritance': True, 'abstract': True}

但是现在当我尝试使用 Component.objects().all()Component 获取文档时,我得到了这个错误:

AttributeError: type object 'Component' has no attribute 'objects'

我应该创建一个基本文档并从中抽象出我的两个集合,还是有更简单的方法来解决这个问题?

更新

即使我创建了一个基础 class 并从中继承了两个 classes:

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()

当我尝试 Component.objects.all() 时,结果将是空列表。

更新 2 如果我用 .save() 添加一个 component,我可以用 Component.objects.all() 得到那个。但是已经保存在该集合中的其余文档呢?我怎样才能恢复它们?

因为我没有得到答案,所以我找到了解决方法。在 meta 中使用 abstract 时,子集合会得到一个名为 _cls 的额外字段,并将集合名称作为值。所以我使用 pymongo 更新现有文档,其中包含一个 _cls 字段并且值等于集合名称,如下所示:

 db["component"].update_many({}, {"$set": {"_cls": "Component"}}, upsert=False, array_filters=None)

完成此操作后,现在我可以使用 mongoengine Component.objects().all() 查询获取文档。

只需使用 'abstract': True 并删除 'allow_inheritance': True。 更多详情 see this.