我有一个Model UnitPattern,它引用另一个Model UnitPatternSet
e.g。
class UnitPattern(db.Model):
unit_pattern_set = db.ReferenceProperty(UnitPatternSet)
在我的视图中我想显示所有UnitPatterns,其unit_pattern_set引用为None,但查询UnitPattern.all()。filter(“unit_pattern_set =”,None)什么都不返回,虽然我总共有5个UnitPatterns,其中2个有'unit_pattern_set'设置,3没有
e.g。
print 'Total',UnitPattern.all().count()
print 'ref set',UnitPattern.all().filter("unit_pattern_set !=", None).count()
print 'ref not set',UnitPattern.all().filter("unit_pattern_set =", None).count()
输出:
Total 5
ref set 2
ref not set 0
查询2和3的总和不应该等于查询1吗?
原因似乎是我之后添加了引用属性unit_pattern_set,并且之前存在这些UnitPattern对象,但是我如何过滤这些实体呢?
答案 0 :(得分:8)
这在docs:
中简明扼要地描述索引仅包含实体 拥有所提到的每一处财产 指数。如果实体没有 财产所指的财产,指数 实体不会出现在索引中, 永远不会是结果 使用索引的查询。
请注意 App Engine数据存储区制作了一个 区分一个实体 不拥有财产和财产 拥有该财产的实体 空值(无)。如果你想 每个实体都是一个 查询的潜在结果,你可以 使用分配的数据模型 默认值(如无)到 查询过滤器使用的属性。
在您的情况下,您有3个实体根本没有设置unit_pattern_set
属性(因为该属性在创建这些实体时未在模型中定义) - 因此这些属性不会不存在于该实体的数据库表示中,因此该实体不会出现在该类实体的该属性的索引中。
丹·桑德森的书Programming Google App Engine在第150页详细解释了这一点(遗憾的是,谷歌图书预览中未提供)
要修复已有的模型,你必须迭代UnitPattern上的查询(我没有测试过以下代码,请在运行实时数据之前检查它):
patterns = UnitPattern.all()
for pattern in patterns:
if not pattern.unit_pattern_set:
pattern.unit_pattern_set = None
pattern.put()
编辑:此外,Updating you model's schema文章讨论了可用于处理架构更改的策略,例如将来。但是,该文章相当陈旧,其方法需要Web浏览器继续按下url以触发下一个作业来更新更多记录 - 现在Task Queues存在,您可以使用一系列任务来进行更改。 article on using deferred.defer有一个你可以利用的框架 - 它完成了少量的工作,捕获了DeadlineExceededError,并使用处理程序对一个新任务进行排队,这个任务将在当前任务停止的地方进行排队。