Google App Engine:从数据存储区“刷新”模型的首选/惯用方式?

时间:2010-06-27 20:26:48

标签: python google-app-engine

我观察到以下情况:( Odp是模型)

o = Odp.get(odpKey)
o.foo = 0
foo()
assert o.foo == 1 # fails

def foo():
    o = Odp.get(odpKey)
    o.foo += 1
    o.put()

当基础数据存储表示更新时,o的第一个副本看起来不会刷新。那么,刷新它的首选方法是什么?

我在想这样的事情:

o = Odp.get(odpKey)
o.foo = 0
foo()
o = Odp.get(o.key())
assert o.foo == 1 # win

或者有更好的方法吗?

1 个答案:

答案 0 :(得分:4)

  

看起来像o的第一个副本不是   当它是潜在的时候会更新   数据存储表示已更新。

正确:在执行函数foo期间,内存中有两个完全独立的对象 - 两者都碰巧绑定到等于o的裸名,在不同的范围内,但这是一个无关的细节(只是进一步混淆了事情; - )。

o = Odp.get(odpKey)
o.foo = 0
foo()
o = Odp.get(o.key())
assert o.foo == 1 # win

仅在第一次“获胜” - 因为o.foo = 0仅影响从未放入数据库的副本,然后o将反弹到第三个​​副本刚从数据库中获取,然后o.foo1 第一个时间(如果foo属性默认为0),而不是后续尝试,因为它每次都增加一个。 之前需要o.put() 才能foo()调用,以使o.foo = 0作业具有任何意义或意义。

更好的想法是让foo函数接受一个可选参数(有问题的对象),只有当没有接收到该参数时才能获得一个新的副本;然后在任何情况下返回它正在处理的对象。我,你有:

o = Odp.get(odpKey)
o.foo = 0
o = foo(o)
assert o.foo == 1  # always OK

def foo(o=None):
  if o is None:
    o = Odp.get(odpKey)
  o.foo += 1
  return o

您可以在某处添加o.put(),但通常最好只在将一组相关更改全部应用于内存中副本时进行保存。基本上完成单个内存中复制的所有工作可以为数据库节省大量的往返次数,从而加快应用程序很多