如何禁用Django查询缓存?

时间:2009-12-11 09:39:13

标签: database django caching

在我的Django应用程序中,我在我的数据库上重复运行相同的查询(例如每10秒)。 然后,我在收到的查询集上创建MD5总和,并将其与我在上一次运行中创建的MD5总和进行比较。如果两者相等,则数据不会更改,并且网页不需要更新。

当我这样做时,数据库中的数据可能会改变。

但是,查询返回相同的查询集,显然是由于query caching

如何禁用查询缓存并在DB上明确执行查询?

5 个答案:

答案 0 :(得分:41)

我遇到了我认为是某种缓存的行为,但事实证明这是欺骗我的数据库事务。

我遇到了问题,在另一个进程中,项目被添加到数据库中,我想监视其他进程的进度,所以我打开了一个django shell并发出以下内容:

>>> MyData.objects.count()
74674

>>> MyData.objects.count()
74674

值并没有改变,即使它实际上在数据库中。我意识到至少我使用MySQL& django设置我在一个事务中,并且在我打开事务时只会看到数据库的“快照”。

由于django中的视图,我定义了自动提交行为,因此每个视图只能查看快照,因为下次调用视图时,它将处于不同的事务中。但对于一段未自动提交的代码,除了在此事务中生成的代码外,它不会看到数据库中的任何更改。

我想我会把这个答案扔给任何可能遇到这种情况的人。

要解决,请提交您的交易,可以手动完成,如下所示:

>> from django.db import transaction
>> transaction.enter_transaction_management()
>> transaction.commit() # Whenever you want to see new data

答案 1 :(得分:9)

查询缓存仅在 QuerySet中应用。换句话说,如果两次评估同一个queryset对象,查询缓存将运行。但是如果你每10秒进行一次查询,可能这是通过一个每次生成一个新进程的cron,所以Django没有办法缓存任何东西。

如果您重复执行完全相同的查询,则数据库自己的缓存可能会生效。您应该查看DBMS的文档,了解如何正确管理它。

答案 2 :(得分:6)

您提供给Django文档的链接意味着以下内容:

>>> print [e.headline for e in Entry.objects.all()]
>>> print [e.pub_date for e in Entry.objects.all()]

为数据库创建两个查询,同时:

>>> queryset = Poll.objects.all()
>>> print [p.headline for p in queryset] # Evaluate the query set.
>>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.

使用查询缓存,因为您正在访问相同的评估结果。

答案 3 :(得分:1)

非常感谢您的回答,您的回复让我退了一步,重新思考。

为了测试DBMS级别的缓存,我离开了Django并使用了一个shell脚本,我总是很方便地定期查询来自SQLite数据库的数据,而我在第二个shell会话中添加了数据。我添加它们后立即在定期查询中显示新数据,因此此处没有查询缓存。

这使它缩小到Django部分。所涉及的代码不是很复杂,一点日志输出和代码审查揭示了问题:用于获取用于创建MD5总和的查询集的查询有一个错误并且始终为空。因此,MD5总和始终相同。确实看起来像一个缓存的结果 - 数据正在改变,但查询集保持不变。 该问题没有在应用程序中显示,因为使用了不同的查询来获取那里显示的数据。

经验教训:如果你完全不解,那就退后一步,重新思考你的假设。

再次感谢! : - )

答案 4 :(得分:0)

我在django 1.8版上遇到了这个问题。没有直接的方法可以做到这一点,但有一些方法可以通过访问db而不是cache来重新评估和执行查询集。我在Django Queryset Documentation

中找到了它

我用其中一个来处理我的问题。它是查询集的exists()函数。也可以使用len()repr()。他们也为我工作。

实施例

queryset = ModelClass.objects.filter(....)
queryset.exists()

#or len(queryset)
#or repr(queryset)

#Now queryset is re-evaluated.