我正在尝试创建类似文件夹结构的内容以保存到 GAE ndb 数据存储。 我将把顶部根文件夹 (MjlistitemFolder) 保存到数据存储中。 MjlistitemFolder 的 items 属性中可以有许多其他子项 (Mjlistitem)。 最终文件夹项的内容将是以下之一:MjlistitemFolder、MjlistitemJobGeneric、MjlistitemJobApp
如果我在内存中创建这个结构,这一切都会起作用。 但是在 put() 将其删除并从数据存储中重新加载根文件夹后,我没有得到相同的结构。
class Mjlistitem(ndb.Model):
pass
class MjlistitemFolder(Mjlistitem):
title = ndb.StringProperty()
items = ndb.StructuredProperty(Mjlistitem, repeated=True)
class MjlistitemJob(Mjlistitem):
pass
class MjlistitemJobGeneric(MjlistitemJob):
jobtype = ndb.IntegerProperty()
class MjlistitemJobApp(MjlistitemJob):
appleid = ndb.StringProperty()
我收到这些警告:
WARNING 2014-04-04 07:14:17,506 model.py:2359] Skipping unknown structured subproperty (items.items.appleid) in repeated structured property (items of MjlistitemFolder)
WARNING 2014-04-04 07:14:17,506 model.py:2359] Skipping unknown structured subproperty (items.items.jobtype) in repeated structured property (items of MjlistitemFolder)
WARNING 2014-04-04 07:14:17,506 model.py:2359] Skipping unknown structured subproperty (items.items.appleid) in repeated structured property (items of MjlistitemFolder)
似乎 db→instance 进程仅将 items 中的内容呈现为 Mjlistitem 类。我如何使它们显示为真正的继承类?
这就是我创建测试结构的方式:
rootfolder = MjlistitemFolder(title="root")
subfolder = MjlistitemFolder(title="Cool things")
subfolder.items.append(MjlistitemJobApp(appleid="281796108")) # evernote
subfolder.items.append(MjlistitemJobGeneric(jobtype=3)) # phone number
subfolder.items.append(MjlistitemJobApp(appleid="327630330")) # dropbox
rootfolder.items.append(MjlistitemJobGeneric(jobtype=15)) # passbook
rootfolder.items.append(subfolder)
rootfolder.items.append(MjlistitemJobGeneric(jobtype=17)) # appstore
rootfolder.put()
最佳答案
使用带有重复KeyProperty
的Polymodel
需要将 StructuredProperty
更改为 KeyProperty
因为:
TypeError: This StructuredProperty cannot use repeated=True because its model class (Mjlistitem) contains repeated properties (directly or indirectly).
模型
from google.appengine.ext import ndb
from google.appengine.ext.ndb import polymodel
class Mjlistitem(polymodel.PolyModel):
pass
class MjlistitemFolder(Mjlistitem):
title = ndb.StringProperty()
# StructuredProperty won't allow you to apply on nested model, use key property instead
items = ndb.KeyProperty(kind=Mjlistitem, repeated=True)
class MjlistitemJob(Mjlistitem):
pass
class MjlistitemJobGeneric(MjlistitemJob):
jobtype = ndb.IntegerProperty()
class MjlistitemJobApp(MjlistitemJob):
appleid = ndb.StringProperty()
用法
def test():
rootfolder = MjlistitemFolder(title="root")
subfolder = MjlistitemFolder(title="Cool things")
subfolder.items.append(MjlistitemJobApp(appleid="281796108").put()) # evernote
subfolder.items.append(MjlistitemJobGeneric(jobtype=3).put()) # phone number
subfolder.items.append(MjlistitemJobApp(appleid="327630330").put()) # dropbox
rootfolder.items.append(MjlistitemJobGeneric(jobtype=15).put()) # passbook
rootfolder.items.append(subfolder.put())
rootfolder.items.append(MjlistitemJobGeneric(jobtype=17).put()) # appstore
rootfolder.put()
还有一件事需要注意。
如果一个文件夹中的项目太多,则重复属性的性能将不佳,因此最好使用
class Mjlistitem(polymodel.PolyModel):
parent = ndb.KeyProperty(kind="Mjlistitem")
def set_parent(self, parent):
assert isinstance(parent, MjlistitemFolder)
self.parent = parent.key
class MjlistitemFolder(Mjlistitem):
title = ndb.StringProperty()
class MjlistitemJob(Mjlistitem):
pass
class MjlistitemJobGeneric(MjlistitemJob):
jobtype = ndb.IntegerProperty()
class MjlistitemJobApp(MjlistitemJob):
appleid = ndb.StringProperty()
用法
def test():
rootfolder = MjlistitemFolder(title="root")
rootfolder.put()
subfolder = MjlistitemFolder(title="Cool things")
subfolder.set_parent(rootfolder)
subfolder.put()
a = MjlistitemJobApp(appleid="281796108")
a.set_parent(subfolder)
a.put()
b = MjlistitemJobGeneric(jobtype=3)
b.set_parent(subfolder)
b.put()
c = MjlistitemJobApp(appleid="327630330")
c.set_parent(subfolder)
c.put()
关于python - 数据存储中的 GAE 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22856079/