2012-07-21 60 views
5

我的问题是,创建新模型实体的最佳方式是什么,然后立即阅读它。例如,如何创建一个新的模型实体,然后立即读取它?

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几次遇到过这个问题,而且我的解决方案一直很有点冒险。通常我只是将所有内容都放在try或while循环中,直到成功检索到实体。我如何确保始终检索模型实体,而不会发生无限循环(在while循环的情况下)或弄乱我的代码(在try语句的情况下)?

+1

只是在创建时为LeftModel设置了一个键,而不是使用自动生成的键。 – 2012-07-21 09:30:31

+1

+1陈述问题 – msw 2012-07-21 12:25:14

回答

9

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

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

无法查询的原因马上是因为人力资源开发使用的最终一致性模型,这意味着你得到卖出期权将可见最终结果。如果你想要一个一致的结果,那么你必须执行祖先查询,这意味着创建关键的祖先。鉴于你正在创建一棵树,这可能是不实际的。阅读关于为强一致性构造数据https://developers.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency

我没有看到任何原因,您只是不使用刚刚创建的实体而没有附加查询。

+0

+1要放大:“我该如何立即阅读?”你不能,那不是NDB的设计目标,并且有很好的理由,它不能马上得到。 – msw 2012-07-21 12:00:26

+7

澄清:该原因与NDB无关 - 这些HRD查询语义在后端实现。 NDB只是传递坏消息。 (至于OP为什么试图这样做:我的猜测和任何一样好,但我希望这个例子与发生这种事情的真实代码相比简化了,并且/或者他们正在编写某种测试;也许他们也许正在将SQL成语翻译成App Engine。) – 2012-07-21 20:17:53

相关问题