【问题标题】:How can I create a new model entity, and then read it immediately after?如何创建一个新的模型实体,然后立即阅读它?
【发布时间】:2012-07-21 09:21:47
【问题描述】:

我的问题是,创建新模型实体的最佳方法是什么,然后立即阅读。例如,

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 except 或一个 while 循环中,直到成功检索到实体。如何确保始终检索模型实体而不冒无限循环的风险(在 while 循环的情况下)或弄乱我的代码(在 try except 语句的情况下)?

【问题讨论】:

  • 只需在创建时为 LeftModel 设置一个键,而不是使用自动生成的键。

标签: python google-app-engine app-engine-ndb


【解决方案1】:

您为什么在执行put() 后立即尝试通过查询获取对象。

您应该使用您刚刚创建的new_left,并立即将其分配给new_right.left_model = current_left.key中的new_right

您不能立即查询的原因是因为 HRD 使用最终一致性模型,这意味着您的 put 结果最终将是可见的。如果你想要一个一致的结果,那么你必须执行祖先查询,这意味着在创建键中有一个祖先。鉴于您正在创建一棵树,这可能不切实际。阅读有关为强一致性构建数据的信息https://developers.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency

我看不出你为什么不使用刚刚创建的实体而不使用额外的查询。

【讨论】:

  • +1 放大:“我如何立即阅读它?”你不能,这不是 NDB 的设计目标,而且它不能立即可用是有充分理由的。
  • 澄清一下:这个原因与 NDB 无关——这些 HRD 查询语义是在后端实现的。 NDB 只是传递坏消息。 (至于为什么 OP 尝试这样做:我的猜测和任何猜测一样好,但我希望与发生这种情况的真实代码相比,该示例得到了简化,和/或他们正在编写某种测试;他们也可能正在将 SQL 惯用语翻译成 App Engine。)
猜你喜欢
  • 2013-02-19
  • 2011-06-17
  • 1970-01-01
  • 2017-05-09
  • 2023-02-11
  • 2020-08-31
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多