【问题标题】:NDB caching temporary / helper properties. Can I turn it off?NDB 缓存临时/辅助属性。我可以关掉它吗?
【发布时间】:2012-10-04 01:08:50
【问题描述】:

看起来在使用 NDB 时临时变量也被缓存了。

class MyModel(ndb.Model)

    def __init__(self, *args, **kwds):
        self._temporary = []
        ndb.Model.__init__(self, *args, **kwds)

有没有办法不在缓存中存储临时/辅助变量?

编辑:

这是一个证明我的问题的简单测试用例:

#Python imports
import unittest

# GAE imports
from google.appengine.ext import testbed
from google.appengine.datastore import datastore_stub_util
from google.appengine.ext import ndb


class TestModel(ndb.Model):

    username = ndb.StringProperty()

    def __init__(self, *args, **kwds):
        self._temp = []
        ndb.Model.__init__(self, *args, **kwds)

class TestModels(unittest.TestCase):

    def setUp(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()

        self.testbed.init_taskqueue_stub()
        self.testbed.init_urlfetch_stub()
        self.testbed.init_mail_stub()
        self.testbed.init_images_stub()
        self.testbed.init_blobstore_stub()

        self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=1)
        self.testbed.init_datastore_v3_stub(consistency_policy=self.policy)

        self.testbed.init_memcache_stub()
        self.testbed.setup_env(app_id='ndb-test')

    def tearDown(self):
        self.testbed.deactivate()

    def test1(self):

        test_model = TestModel()
        test_model.username = 'Tom'
        test_model._temp = 'Temporary'
        test_model.put()

        test = TestModel.query().fetch(10)

        self.assertEqual(1, len(test))

        test = test[0]

        self.assertEqual('Tom', test.username)
        self.assertEqual([], test._temp)

测试的最后一行 self.assertEqual([], test._temp) 失败,即使我希望它通过。

有没有办法不存储临时/辅助模型属性,或者每次从缓存中加载模型时都有一种更简单的方法来重置它们?

【问题讨论】:

  • 您是否 100% 确定它们已被缓存? Ndb 仅通过键(Key.get())缓存实体,它不应该缓存任何“帮助”变量(以下划线开头)。如果我运行您的代码,创建新实体,填充 _temporary 列表并将其放入,ndb 不会存储任何这些值。您能否描述一下您是如何对其进行测试的,以及您是如何获得缓存的结果的?
  • 感谢您的回复。请查看我的编辑。

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


【解决方案1】:

NDB 有几个缓存 - 实例内存和 memcache。在实例内存中,实际实体本身被缓存,因此在同一个请求中的多个 get 调用将返回同一个实体对象。

只要您使用启用了缓存的 NDB,这就是您必须处理的事情 - 例如,首先不要在实体上存储“临时”数据。

【讨论】:

  • 感谢您的回复。 GAE 文档说:“属性的名称用作实体上相应属性的名称。名称以下划线 (_) 开头的模型实例属性将被忽略,因此您的应用程序可以使用此类属性将数据存储在未保存到数据存储区的模型实例。”所以我认为在使用上下文缓存时它们也应该被忽略,但事实并非如此。我正在寻找一种解决方案,以便在从上下文缓存中检索实体时“清除”它们。
  • NDB 缓存不是将内容存储到数据存储区 - 它是在内存中缓存内容。由于它是同一个实例,因此在不了解模型细节的情况下,它无法进入并清除事物。无论您在此处存储什么,几乎可以肯定一开始就不应该与模型相关联。
  • “NDB 缓存不是将内容存储到数据存储区 - 它是在内存中缓存内容。” - 我对此很清楚。我的问题的部分答案可以在这里找到:stackoverflow.com/questions/12727233/… 和这里:stackoverflow.com/questions/12083254/…
  • 我的意思是文档的那一部分是无关紧要的——它指的是实体如何存储在数据存储中,而不是 NDB 如何缓存它们。此外,NDB 在文档中解释了它是如何缓存的。禁用缓存是对此的一种极端反应,并且会影响性​​能 - 您最好将这些“临时”属性从模型中移出,或者自己清除它们。这些属性的性质是什么?
  • 我在模型中添加了一些临时/辅助属性和一些属性设置器,这样我就可以跟踪哪些属性发生了变化,然后使用这些信息来更新一些分片计数器,这些分片计数器保存了我所拥有的数据的统计信息数据存储。正如您指出的那样,解决方案是不要将这些数据保存在模型中。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-10-20
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 2015-05-24
  • 1970-01-01
相关资源
最近更新 更多