我已经声明了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键的热链接,正如预期的那样。
有人能告诉我这里出了什么问题吗?具体来说,我很想知道为什么它在本地运行而不是在部署时。
答案 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
设定为您想要的数量。是的,这需要获取所有这些,但计数并不比获取快得多。