一尘不染

如何强制Django忽略所有缓存并重新加载数据?

django

我正在使用未从HTTP请求调用的进程中的Django数据库模型。该过程应该每隔几秒钟轮询一次新数据并对其进行一些处理。我有一个循环,它hibernate了几秒钟,然后从数据库中获取所有未处理的数据。

我看到的是,在第一次获取之后,该进程再也看不到任何新数据。我进行了一些测试,尽管每次我都在构建新的QuerySet,但看起来Django正在缓存结果。为了验证这一点,我从Python shell做到了这一点:

>>> MyModel.objects.count()
885
# (Here I added some more data from another process.)
>>> MyModel.objects.count()
885
>>> MyModel.objects.update()
0
>>> MyModel.objects.count()
1025

如你所见,添加新数据不会更改结果计数。但是,调用管理器的update()方法似乎可以解决此问题。

我找不到关于该update()方法的任何文档,也不知道它可能还会做些其他的坏事。

我的问题是,为什么我会看到这种缓存行为,这与Django文档所说的相反?以及如何防止它发生?


阅读 549

收藏
2020-03-26

共1个答案

一尘不染

现在,Django 1.6已在MySQL中启用自动提交,这不再是问题。flush_transaction()无论你的MySQL是处于REPEATABLE-READ(默认)READ-COMMITTED模式还是事务隔离模式,上面的示例现在都可以正常运行而无需编写代码。

在非自动提交模式下运行的早期Django版本中发生的事情是,第一条select语句打开了一个事务。由于MySQL的默认模式是REPEATABLE-READ这意味着后续select语句不会读取对数据库的任何更新-因此需要flush_transaction()上面的代码来停止事务并开始新的事务。

仍然有你为什么要使用READ-COMMITTED事务隔离的原因。如果要在终端1中进行事务处理,并且想要查看来自终端2的写入,则需要使用READ-COMMITTED

flush_transaction()代码现在在Django 1.6中会产生弃用警告,因此建议你将其删除。

2020-03-26