flask - Mongoengine EmbeddedDocumentListField // 我只能访问get方法
问题描述
我正在为我的学校创建一个数据库。有一个学生文档,其中包含成人的 EmbeddedDocumentListField。我正在尝试使用 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)
这将返回名为 editAdult 的对象,该对象具有预期的属性,但没有方法。我现在想更新该对象中的值。我可以通过做来查看我想要调用的方法。
dir(editUser.adults)
但看不到方法
dir(editAdult)
根据我对文档的阅读,我应该能够做到这一点。
editAdult.update(fname="Juanita", lname="Sanchez")
这给出了错误:AttributeError:“成人”对象没有属性“更新”。但无法弄清楚如何在该上下文中使用这些方法。我试过了
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 Route
@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()
为了完整起见,这里是删除 EmbeddedDocument 记录的 Flask 路线
@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。:(
推荐阅读
- mysql - 如何使用 node 和 mysql 将值从 DB 返回到变量?
- android - Firebase DB 离线缓存如何在 android 上工作?
- excel - 获取不在列表中的值的数量
- c# - 将自包含的 .Net Core Windows 窗体应用程序发布到单个文件中
- bash - 只读以 bash 中传递给脚本的变量开头的行
- firebase - 使用 firebase 在颤振中设置“结构化查询”时出错
- docker - 将串行 USB 设备暴露给容器
- ios - iOS Firebase / Firestore - 数组计数多少次读取
- ios - UITextView 用新行向上滚动表格视图
- windows - 如何让 AWS GPU 在 Windows Server 上运行?