我的问题是,创建新模型实体的最佳方法是什么,然后立即阅读。例如,
class LeftModel(ndb.Model):
name = ndb.StringProperty(default = "John")
date = ndb.DateTimeProperty(auto_now_add=True)
class RightModel(ndb.Model):
left_model = ndb.KeyProperty(kind=LeftModel)
interesting_fact = ndb.StringProperty(default = "Nothing")
def do_this(self):
# Create a new model entity
new_left = LeftModel()
new_left.name = "George"
new_left.put()
# Retrieve the entity just created
current_left = LeftModel.query().filter(LeftModel.name == "George").get()
# Create a new entity which references the entity just created and retrieved
new_right = RightModel()
new_right.left_model = current_left.key
new_right.interesting_fact = "Something"
new_right.put()
这经常引发一个例外:
AttributeError: 'NoneType' object has no attribute 'key'
即。检索新的LeftModel实体是不成功的。我用appengine几次遇到这个问题,我的解决方案总是有点hacky。通常我只是将所有内容放在try while或while循环中,直到成功检索到实体。如何确保始终检索模型实体而不运行无限循环的风险(在while循环的情况下)或弄乱我的代码(在try语句除外的情况下)?
答案 0 :(得分:9)
为什么在执行put()
后立即尝试通过查询获取对象。
您应该使用刚创建的new_left
并立即将其分配给new_right,如new_right.left_model = current_left.key
您无法立即查询的原因是因为HRD使用最终一致性模型,这意味着您的结果将最终可见。如果您想要一致的结果,那么您必须执行祖先查询,这意味着创建时密钥中的祖先。鉴于您正在创建一棵树,这可能不实用。阅读有关构建强一致性数据https://developers.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency
的内容我没有看到任何理由您不使用刚创建的实体而没有额外的查询。