【问题标题】:why does google datastore second query returns modified instance (without calling put after first query)?为什么谷歌数据存储第二个查询返回修改后的实例(第一次查询后不调用 put)?
【发布时间】:2016-06-22 18:43:53
【问题描述】:

我在查询数据存储时遇到了一个非常违反直觉的情况。

步骤如下:

  1. 使用第一个查询检索对象:list_objects = MyModel.query(cls.name == name).fetch()

  2. 修改list_objects:for o in list_objects: o.value = new_value

  3. 第二次检索对象:list_objects_2 = MyModel.query(cls.name == name).fetch()

  4. 现在 list_objects_2 中的所有对象都有 new_value,尽管在第 2 步中,从未调用 put 来实际修改数据存储,我检查了我的数据存储,其值为原始值

  5. 修改list_objects_2:for o in list_objects_2: o.value = new_new_value,现在list_objects1都有new_new_value

我也试过fetch(keys_only = True)k.get(),但同样的问题。

我的印象是查询是针对实际数据存储的,为什么它一直返回相同的实例而不是构造新的实例?是因为某种缓存吗?

【问题讨论】:

  • 听起来不对,你能举出可重现的例子吗?

标签: google-app-engine app-engine-ndb google-cloud-datastore


【解决方案1】:

查看这篇文章https://cloud.google.com/appengine/docs/python/ndb/cache

上下文缓存很快;这个缓存存在于内存中。当一个新开发银行 函数写入数据存储,它还写入上下文 缓存。当 NDB 函数读取实体时,它会检查上下文 先缓存。如果在那里找到实体,则没有 Datastore 交互 发生。

当 NDB 函数查询 Datastore 时,结果列表为 从数据存储中检索。但是,如果任何个别结果是 上下文缓存,它用于代替从中检索的值 数据存储区查询。查询结果写回上下文中 如果缓存策略如此,则缓存(但从不用于 Memcache)。

1)list_objects = MyModel.query(cls.name == name).fetch()

预热上下文缓存

2)for o in list_objects: o.value = new_value

只修改内存中的对象

3)list_objects_2 = MyModel.query(cls.name == name).fetch()

实际上没有发生数据存储交互,你从缓存中获取相同的对象

4)for o in list_objects_2: o.value = new_new_value

只修改内存中的对象

5) fetch(keys_only = True)k.get() 没有发生数据存储交互

【讨论】:

  • 谢谢!就是这样。我在反复试验后发现了这一点,它与进程内缓存有关,如果我添加 fetch(use_cache=False),则查询返回新实例,尽管我有点惊讶为什么进程内缓存被打开默认情况下。
猜你喜欢
  • 2021-02-16
  • 2017-04-10
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多