NDB模型的自定义属性在部署时未返回正确的值

时间:2015-11-26 15:19:42

标签: python google-app-engine google-cloud-datastore app-engine-ndb

我已经声明了2个ndb模型如下:

class Event(ndb.Model):
    event_type = ndb.KeyProperty()

    @property
    def installments(self):
        return EventInstallment.query().filter(EventInstallment.event == self.key).count()

class EventInstallment(ndb.Model):
    event = ndb.KeyProperty()

我坚持使用Event类型的单个实体和另一个EventInstallment类型的实体。 EventInstallment.event是声明的Event实体的Key。以下查询在本地运行时工作(即返回1),但在部署时不工作:

event_query = Event.query()
event_query = event_query.filter(ndb.GenericProperty('installments') > 0)
print event_query.count()

我已经清除了memcache,并仔细检查了EventInstallment的所有属性是否正确。在datastoreviewer中打开EventInstallment实体时,它具有Event键的热链接,正如预期的那样。

有人能告诉我这里出了什么问题吗?具体来说,我很想知道为什么它在本地运行而不是在部署时。

1 个答案:

答案 0 :(得分:2)

filter必须能够在数据存储区中运行,并且在已部署的应用中,filter(ndb.GenericProperty('installments') > 0)显然不能(模拟dev_appserver所做的不是100%准确,我打赌它的作者从未梦想过检查类似的东西。)

相反,您想要的是ComputedProperty,它会在put时计算并实际发送到数据存储区,允许数据存储区对其执行搜索。即:

class Event(ndb.Model):
    event_type = ndb.KeyProperty()

    @property
    def _installments(self):
        return EventInstallment.query().filter(EventInstallment.event == self.key).count()

    installments = ndb.ComputedProperty(lambda self: self._installments)

现在,filter(Event.installments > 0)将起作用 - 只要EventInstallment实体上次Event put实体的数量>是积极的。 (当Event实体被添加,​​删除或更改时,数据存储区不会重新运行任何代码来更新EventInstallment实体; ComputedProperty计算在put时间在它所属的实体上,它是在事物的appengine实例端计算的,即在应用程序级代码"中,就在实体被发送到数据存储端之前的事物中)。

您可能希望以相反的方式工作:查询EventInstallment个实体,制作一组event个属性以删除重复项,并使用len设定为您想要的数量。是的,这需要获取所有这些,但计数并不比获取快得多。