【问题标题】:Why Redis removes relations in objects if related object is removed from database?如果从数据库中删除相关对象,为什么 Redis 会删除对象中的关系?
【发布时间】:2015-05-15 17:15:51
【问题描述】:

我有 Django、PostgreSQL 和 Redis。我有具有外键和 m2m 关系的模型。每天我都在缓存一堆对象并在午夜删除它们的缓存。问题是当我从数据库中删除对象时(白天)-缓存中具有关系的字段也发生了变化(此对象的 id 已从外键和 m2m 中删除)。正如我在 Redis 文档中所读到的 - 所有对象都作为哈希存储在服务器的 RAM 中。我无法理解数据库更改如何影响 RAM 缓存。那么为什么会发生这种情况,我该如何防止这种行为呢?

例子:

# Model
class Item(models.Model):
    ...
    places = models.ManyToManyField(Place, verbose_name=_('Places'), related_name='items', null=True, blank=True)


# In view
items = Item.objects.all()
cache.set(key, items, None)

然后在 django admin 中,我正在删除其中一个 Places,在 shell 中,我正在获取缓存的项目:

items = cache.get(key)

并手动检查检索到的项目的位置 - 该位置已从所有相关项目中删除。这不好。

【问题讨论】:

  • 您没有提供足够的详细信息。你究竟是如何做你正在做的事情的?
  • 感谢您的评论。我已经更新了问题。

标签: python django postgresql caching redis


【解决方案1】:

Django 正在删除它,因为你告诉了它。您在 Django 中使用关系映射,然后告诉它删除其中一项,然后它正确地执行了。

https://docs.djangoproject.com/en/1.7/ref/models/relations/ 的文档中对此进行了解释

此外,调用 item.objects.all() 会执行对 SQL 数据库的查询,而不是使用缓存中的内容。这是因为此时您在 ORM 而不是缓存上进行操作。相关,将您的“项目”结果存储在缓存中只会缓存结果,而不是所有相关项目。

【讨论】:

  • Django 从数据库中删除关系,但缓存中的关系不应该受到影响,但确实如此。从数据库中删除“地点”后,我立即检查缓存的“项目”。
  • 您究竟是如何“手动检查检索到的项目的位置”?您是否在迭代缓存中的内容并要求 Django 获取它们?你从 item.get(key) 得到的字符串和你放入的字符串一样吗?
  • 您究竟是如何“手动检查检索到的项目的位置”? “...从所有相关项目中删除”是什么意思? Redis 无法执行您所说的操作,因此 Django 正在更新您的缓存,或者您没有缓存您认为正在缓存的内容。没有具体细节我们不能说。就我们所知,UpdateCacheMiddleware 正在为您更新缓存,或者您缓存的只是一个项目列表。您没有提供足够的详细信息来了解。
  • 哇,我很笨,对不起。我保存了不像字符串的对象,我保存了一个 QuerySet 来缓存,在获得特定的项目表单缓存后,我创建了“cached_item.objects.all()”,它对数据库进行了 SELECT 查询。所以这就是为什么我找不到相关的地方 - 它没有被物品缓存。请添加注释,当您缓存 QuerySet 时不会缓存相关项目,我会批准您的回答。我还有一个问题 - items = Item.objects.all() 和 items = list(Item.objects.all()) 之间有什么区别吗?谢谢!
  • 不傻,只是不知道对对象的管理器进行方法调用会在 ORM 上运行,即使您已将其从缓存中拉出。我已经添加了关于缓存不缓存相关数据的措辞。
猜你喜欢
  • 2017-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多