我观察到以下情况:(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
或者有更好的方法吗?
最佳答案
t looks like the first copy of o isn't refreshed when it's underlying datastore representation is updated.
正确:在函数 foo
执行过程中,内存中有两个完全独立的对象——两者都恰好绑定(bind)到等于 o
的裸名,在不同的作用域中,但这是一个不相关的细节(只是进一步混淆事情;-)。
o = Odp.get(odpKey)
o.foo = 0
foo()
o = Odp.get(o.key())
assert o.foo == 1 # win
仅第一次“win” - 因为o.foo = 0
仅影响从未放入数据库的副本,然后o
被反弹到刚刚从数据库获取的第三副本,那么o.foo
第一次将是1
(如果foo
属性默认为 0
),但在后续尝试中不会,因为它每次都会增加 1。在调用 foo()
之前,您需要一个 o.put()
来使 o.foo = 0
> 赋值具有任何意义或意义。
更好的想法是让 foo
函数接受一个可选参数(有问题的对象),并仅在它没有接收到时才获取新副本那个论点;然后无论如何返回它正在处理的对象。 IOW,你会:
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()
,但通常最好仅在一组相关更改全部应用于内存中副本时才保存。在单个内存副本上完成基本上所有的工作可以节省大量的数据库往返次数,从而大大加快您的应用程序的速度。
关于python - 谷歌应用引擎: Preferred/idiomatic way to "refresh" a model from the datastore?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3128778/