我有一个带有重复属性的ndb模型:
class MyModel(ndb.Model):
foo = ndb.KeyProperty(repeated=True)
我想在foo
上执行不等式过滤器,这意味着我需要按foo
排序:
query = MyModel.query()
query = query.filter(MyModel.foo != my_key)
# I don't actually care about doing this, but I have to because of the inequality filter.
query = query.order(MyModel.foo)
我希望查询包含foo为空的实体。如果我把一个虚拟字段放入foo中,它就可以工作:
def _pre_put_hook(self):
if not self.foo:
self.foo.append(ndb.Key('Dummy Kind', 'Dummy ID'))
但这似乎并不是一种干净的方法。还有更好的方法吗?
答案 0 :(得分:4)
当数据存储区在其索引中存储repeated=True
的属性时,它为stores one row for each value。这意味着如果您有一个空的重复属性,它将不会显示在您的EntitiesByProperty索引中。这意味着无法查询空的重复属性。
有几种选择,但每种选择都有自己的权衡:
您建议的这种方法的好处是您现有的查询将为您提供所需的结果。但是,当您添加实际数据时,您必须处理清理虚拟密钥。
ComputedProperty
。您可以为foo属性的大小添加新属性:
class MyModel(ndb.Model):
foo = ndb.KeyProperty(repeated=True)
foo_len = ndb.ComputedProperty(lambda self: len(self.foo))
但是,要获取foo
值与my_key
不匹配或为空的实体,您必须编写两个查询才能获得结果:
ndb.gql("SELECT * FROM MyModel WHERE foo != :1", my_key)
ndb.gql("SELECT * FROM MyModel WHERE foo_len == :1" 0)
请注意,如果foo
没有重复,请使用以下查询获得所需结果:
ndb.gql("SELECT * FROM MyModel WHERE foo != :1", my_key)
即使没有空列表情况,在使用重复属性时也需要小心。特别是,只有一个重复的属性必须与您的密钥匹配。因此,自my_key2 != my_key
以来,下面定义的模型仍会与您的查询匹配:
MyModel(foo=[my_key, my_key2])