如何在测试中清除/失效NDB缓存

1 投票
3 回答
1202 浏览
提问于 2025-04-17 23:20

我有一个简单的 NDB 模型,里面有一个实例属性,但这个属性不是 NDB 属性。我想测试一下,当这个实体被保存到数据存储中并再取出来时,这个属性的值是否会丢失。

现在,当我从数据存储中取出这个实体时,它和之前放进去的是同一个实例。

有没有办法可以通过编程的方式清除/失效 内存缓存NDB 内存缓存

这个例子是一个 pytest 测试,抱歉。

from google.appengine.ext import testbed, ndb


class User(ndb.Model):
    name = ndb.TextProperty()
    foo = None


class TestNDBModel(object):

    def setup(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

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

    def test_foo(self):
        user = User(name='Andy')
        assert user.name == 'Andy'
        assert user.foo is None
        user.foo = 123
        assert user.foo == 123
        user_key = user.put()

        # Here I need to clear the cache somehow,
        # so that the entity must be retrieved from datastore

        retrieved_user = user_key.get()

        # These two will now fail
        assert retrieved_user is not user
        assert retrieved_user.foo is None

3 个回答

1

我也遇到过同样的问题,一直在找解决办法。这个方法可以解决这个问题:

ndb.get_context().clear_cache()
1

你似乎用错了方法来给 retrieved_user 赋值。可以试试下面这个:

retrieved_user = user_key.delete(use_datastore=False)

想了解更多信息,可以查看以下链接:

https://developers.google.com/appengine/docs/python/ndb/functions#context_options

1

解决办法是,当你把一个实体放入数据库时,可以通过 entity.put(use_cache=False, use_memcache=False) 来防止它被缓存。

from google.appengine.ext import testbed, ndb


class User(ndb.Model):
    name = ndb.TextProperty()
    foo = None


class TestNDBModel(object):

    def setup(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

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

    def test_foo(self):
        user = User(name='Andy')
        assert user.name == 'Andy'
        assert user.foo is None
        user.foo = 123
        assert user.foo == 123

        # This prevents the entity to be cached
        user_key = user.put(use_cache=False, use_memcache=False)

        # The entity is now retrieved from DB
        retrieved_user = user_key.get()

        # These two will now pass
        assert retrieved_user is not user
        assert retrieved_user.foo is None

撰写回答