python - 数据存储中的 GAE 继承

标签 python google-app-engine inheritance

我正在尝试创建类似文件夹结构的内容以保存到 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()

最佳答案

使用带有重复KeyPropertyPolymodel

需要将 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/

相关文章:

python - 在 HDF 存储中构建数据结构

python - 如何找到以 <!-- 开头的 HTML 注释的第一个实例? (Python)

python - 即使 is_valid 为 True,Serializer validated_data 也是空的

php - Google Appengine 1.9.3/4 和 WordPress 3.9 管理员用户在本地主机上功能不全

Java服务器如何处理Client请求并响应呢?

java - java构造函数的默认参数

java - 如何在java中使用数据类,而不使用getter方法?

python - 如何将 jpeg 数据加载、标记和馈送到 Tensorflow 中?

java - GAE : Getting runtime exception when running the (java) guestbook tutorial (working fine locally)

ios - 2个 View Controller ,每个都有自己的xib,其中一个是另一个的子类?