Mongoengine EmbeddedDocumentListField // 我只能访问get方法

Mongoengine EmbeddedDocumentListField // I can only access the get menthod

我正在为我的学校创建一个数据库。有一个 Student Document 的 EmbeddedDocumentListField 为 Adults。我正在尝试使用 EmbeddedDocumentListField 方法更新现有的 EmbeddedDocuments,但 save() 和 update() 都给我错误。 get() 似乎有效。

class Adult(EmbeddedDocument):
    relation = StringField() # Adult, Mother, Father, Grandmother...
    ...
    notes = StringField()

class Student(Document):
    afname = StringField()
    alname = StringField()
    ...
    adults = EmbeddedDocumentListField('Adult')

我能够成功使用get方法

@app.route('/editadult/<aeriesid>/<adultoid>')
def editadult(aeriesid,adultoid):
    editUser = User.objects.get(aeriesid=aeriesid)
    editAdult = editUser.adults.get(oid=adultoid)

这个 returns 名为 editAdult 的对象具有预期的属性,但没有方法。我现在想更新该对象中的值。我可以看到我想调用的方法。

dir(editUser.adults)

但是看不到方法

dir(editAdult)

根据我对文档的阅读,我应该能够做到这一点。

editAdult.update(fname="Juanita", lname="Sanchez")

这给出了错误:AttributeError: 'Adult' object has no attribute 'update'。 但无法弄清楚如何在该上下文中使用这些方法。 我试过了

editAdult.fname = "Juanita"
editAdult.lname = "Sanchez"
editAdult.save()

但这给出了错误:AttributeError: 'Adult' object has no attribute 'save'

文档很少。 Mongoengine 告诉我这些方法是什么,但没有示例。 http://docs.mongoengine.org/apireference.html#embedded-document-querying GitHub 给出了很好的例子,但我无法让它们发挥作用。 https://github.com/MongoEngine/mongoengine/pull/826

我正在使用 Mongoengine 0.20.0

经过大量的反复试验,我明白了这一点。使用此数据结构:

class Adult(EmbeddedDocument):
    relation = StringField() # Adult, Mother, Father, Grandmother...
    fname = StringField()
    lname = StringField()
    ...
    notes = StringField()

class Student(Document):
    afname = StringField()
    alname = StringField()
    ...
    adults = EmbeddedDocumentListField('Adult')

然后我创建了这条 Flask 路线

@app.route('/editadult/<aeriesid>/<adultoid>')
def editadult(aeriesid,adultoid):
    editUser = User.objects.get(aeriesid=aeriesid)
    editAdult = editUser.adults.get(oid=adultoid)

adultoid 是成人的唯一标识符,aeriesid 是学生的唯一标识符,所以我知道这两个都将检索到一条记录。

我遗漏的部分是,虽然 editAdult 对象完全包含我想要的值,但它不是 EmbeddedDocumentListObject,因此它不包含方法。因此,上面的 get() 命令是基本的 MongoEngine get() 而不是 EmbeddedDocumentFieldList 中的 get() 方法。 (我在下面展示了 EmbeddedDocumentListField get())

这就是我所缺少的。这就是您在 EmbeddedDocumentListField 中使用 update() 方法的方式。

    editUser.adults.filter(oid=adultoid).update(
        relation = form.relation.data,
        fname = form.fname.data,
        lname = form.lname.data,
        ...
        notes = form.notes.data
    )

我不确定这个更新命令是否会更新所有过滤的记录。在我的例子中,只可能返回一条记录,因为我正在过滤 uniqueid。接下来,事实证明 EmbeddedDocumentListField() update() 不像在基本 update() 方法中那样保存,因此您必须执行此操作。这个事实实际上在 MongoEngine 文档中有详细记录。 http://docs.mongoengine.org/apireference.html?highlight=embedded%20documents#embedded-document-querying

editUser.adults.filter(oid=adultoid).save()

最后,还有另一种方法来执行原始的 get() 命令:

editAdult2 = editUser.adults.filter(oid=adultoid).get()

为了完整起见,这里是 Flask 删除 EmbeddedDocument 记录的路径

@app.route('/deleteadult/<aeriesid>/<adultoid>')
def deleteadult(aeriesid,adultoid):
    editUser = User.objects.get(aeriesid=aeriesid)
    editAdult = editUser.adults.get(oid=adultoid)
    editUser.adults.filter(oid=adultoid).delete()
    editUser.adults.filter(oid=adultoid).save()

我希望这对其他人有帮助。学习这个的过程非常艰难,而且大多只是反复试验。我考虑回到 SQLAlchemy。 :(