如何创建新的模型实体,然后立即读取?

use*_*852 5 python google-app-engine app-engine-ndb

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

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()
Run Code Online (Sandbox Code Playgroud)

这经常抛出一个例外:

AttributeError: 'NoneType' object has no attribute 'key'
Run Code Online (Sandbox Code Playgroud)

即,检索新的LeftModel实体是不成功的.我用appengine几次遇到这个问题,我的解决方案总是有点hacky.通常我只是将所有内容放在try while或while循环中,直到成功检索到实体.如何确保始终检索模型实体而不运行无限循环的风险(在while循环的情况下)或弄乱我的代码(在try语句除外的情况下)?

Tim*_*man 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

我没有看到任何理由你不使用刚刚创建的实体而没有额外的查询.

  • 澄清一下:这个原因与NDB无关 - 这些HRD查询语义是在后端实现的.NDB只是传递了坏消息.(至于为什么OP正在尝试这个:我的猜测和任何一样好,但我希望这个例子比实际发生的代码更简单,和/或他们正在编写某种测试;也许他们也许正在将SQL习语翻译成App Engine.) (7认同)