【问题标题】:Django ORM queries fail to select new objectsDjango ORM 查询无法选择新对象
【发布时间】:2011-10-25 01:54:32
【问题描述】:

设置:

  • Python 脚本 A 每 15 分钟向数据库插入一次数据
  • Python 脚本 B 每隔几分钟查询最后 5 个条目

两者都使用 django 的 ORM,相同的 MySQL DB 和相同的 DB 用户帐户(相同的 settings.py 文件)

问题:
B 只能获取在运行之前插入的条目。好像 B 正在使用冻结的 DB 运行,在 B 第一次连接到 DB 时冻结。

怎么会?
我可以在 django 中控制这种行为吗?

【问题讨论】:

  • B 使用以下语法进行查询:MyModel.objects.filter(a_datetime_field__gte=datetime.datetime(2011,08,11,14,15,0)).order_by('a_datetime_field')
  • 如果您使用 MySQL 和 InnoDB,请注意默认隔离级别是 REPEATABLE-READ。您可能更喜欢 READ-COMMITED。请参阅此答案以获取替代解决方案:stackoverflow.com/questions/3346124/…

标签: python mysql django orm


【解决方案1】:

我在尝试使用 Django 测试解决类似情况时发现了这个 stackoverflow 问题:在测试中,我修改了 Django 模型对象,但是这些更改没有反映在数据库中,因此数据库阅读器在第二个线程中可以检测到更改。解决方案是从TransactionTestCase 继承我的测试类,而不是默认的 django.test.TestCase。

【讨论】:

    【解决方案2】:

    如果您要重用相同的 Manager 对象,则必须牢记it's caching。要解决这个问题,您必须手动更新。

    这将在每次迭代中返回相同的结果:

    while True:
       same_every_time = AClass.objects.all().order_by('-id')[:5]
       sleep(300)
    

    为了使其正常工作,您必须添加更新:

    while True:
       AClass.objects.update()
       updated_results = AClass.objects.all().order_by('-id')[:5]
       sleep(300)
    

    【讨论】:

    • 成功了!!我似乎找不到关于此的文档 - 你有机会发布参考吗?
    • 我添加了指向缓存文档的链接。我不确定在哪里找到.update() 解决方案,我到处寻找使缓存无效的方法。我在一些 Django 论坛上找到了它,但现在不记得在哪里了。我在生产代码中有这个并且运行良好。
    • REPEATABLE-READ 事务隔离级别(MySQL 默认),并且没有提交 SELECT 语句也可以解释这个问题。但是 objects.update() 也解决了这个问题......
    【解决方案3】:

    Django 本身使用一种容器管理的持久性。这意味着数据库事务在上游响应级联期间由中间件提交。

    如果你自己使用 Django ORM,你应该确保事务的实际提交:

    from django.db import transaction
    
    def my_task(whatever):
        MyModel.objects.create(...)
        # do whatever
        transaction.commit()
        return 'my_result'
    

    【讨论】:

    • 我已经通过多种方式保证了提交 - 使用@commit_on_success,通过我自己实时查看数据,通过查看 MySQL 日志......问题不在于插入,而在于数据查询
    • 事实上,@vartec 的答案可能是正确的。管理器使用内部缓存,通常在请求/响应周期中使用,因此数据始终保持一致,但另一方面,对于长时间运行的脚本,您应该使其无效。
    猜你喜欢
    • 2013-05-19
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2020-12-03
    • 2021-12-19
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多