【发布时间】:2014-06-06 23:37:58
【问题描述】:
我正在为 KeyProperty 查询而苦苦挣扎,但看不出有什么问题。
我的模特是
class MyList(ndb.Model):
user = ndb.KeyProperty(indexed=True)
status = ndb.BooleanProperty(default=True)
items = ndb.StructuredProperty(MyRef, repeated=True, indexed=False)
我使用适当的数据创建了一个 MyList 实例,并且可以正常运行以下内容
cls = MyList
lists = cls.query().fetch()
返回
[MyList(key=Key('MyList', 12), status=True, items=..., user=Key('User', 11))]
但是当我尝试按用户过滤时它失败了,即查找用户等于特定实体的列表;即使使用我刚刚用于插入的那个,或者来自上一个查询结果。
key = lists[0].user
lists = cls.query(cls.user=key).fetch()
返回
[]
但是使用status=True 作为过滤器可以正常工作,而且我看不到缺少什么?
我应该添加它发生在具有以下 v3_stub 的单元测试环境中
self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)
self.testbed.init_datastore_v3_stub(
require_indexes=True,
root_path="%s/../"%(os.path.dirname(__file__)),
consistency_policy=self.policy
)
【问题讨论】:
-
这是最终一致性的产物。它在 SDK 中进行仿真,在使用 SDK 进行测试时,您可以选择如何仿真或不进行仿真。事实证明,您知道您可以检索实体,因此它存在。关闭开发环境中的最终一致性作为另一项检查。但是你必须在你的设计中处理这个问题。
-
@TimHoffman:没错,如果我设置probability=1,它就可以正常工作,谢谢!然而,我不明白为什么不带参数的 query() 以及另一个过滤器(例如 status=True)有效。这是否意味着由于最终一致性,尚未创建索引?我认为最终一致性状态是“全有或全无”,而不是像这种情况下的“中间”,只有一些索引返回正确的数据。这是一个错误吗?
-
我相信每个索引都会在它自己的时间更新。但是,您正在使用 SDK,它充其量是真实环境的近似值。您应该编写代码来处理 SDK 最终行为,因为这可能是最坏的情况。如果你的设计可以处理这个问题,那么你就可以处理生产。另一方面,如果您的设计仅在设置概率 = 1 时才有效,那么您处于滑坡上,并且在生产中会遇到问题。
-
@TimHoffman 我已经确保概率 = 0 适用于所有 get() 等,但索引问题有点 PITA。我添加了额外的缓存,所以现在可以正常工作了。我仍然认为不同的索引时间令人困惑(或者至少没有很好的记录)。再次感谢!
-
索引已经/将要过时的事实是最终一致性的关键。正如您所发现的,get() 始终是一致的,除非 google 基础设施出现故障 - (我们已经看到)但是索引在更新之前总是有可变的时间量(通常很短)。这适用于删除和写入。
标签: google-app-engine app-engine-ndb