芹菜任务中缺少与Django相关的对象(竞赛条件?) [英] Django related objects are missing from celery task (race condition?)

查看:75
本文介绍了芹菜任务中缺少与Django相关的对象(竞赛条件?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

奇怪的行为,我不知道该如何解释。我有一个模型,跟踪,并带有一些相关的。我称一个celery任务来执行一些带点的计算,它们似乎在方法本身中完全可以实现,但是在celery任务中不可用。

Strange behavior, that I don't know how to explain. I've got a model, Track, with some related points. I call a celery task to performs some calculations with points, and they seem to be perfectly reachable in the method itself, but unavailable in celery task.

@shared_task
def my_task(track):
    print 'in the task', track.id, track.points.all().count()

def some_method():
    t = Track()
    t.save()
    t = fill_with_points(t)  # creating points, attaching them to a Track
    t.save()
    print 'before the task', track.id, track.points.all().count()
    my_task.delay(t)

打印以下内容:

before the task, 21346, 2971
in the task, 21346, 0

奇怪的事情,当我在 my_task 的第一行或在完全调用 my_task 之前放置time.sleep(10)时,效果很好,就像有一些比赛条件。但是第一行显示的内容清楚地表明,在进行选择查询时, points 在数据库中可用( track.points.all()。count ())。

Strange thing though, when I put a time.sleep(10) at the first line of my_task or before calling my_task at all, it works out well, like there's some race condition. But the first printed line clearly says that points are available in the database, when it makes a select query (track.points.all().count()).

推荐答案

因此,我已经使用 django-transaction-hooks 。替换我的数据库后端看起来仍然有些恐怖,但是 django-celery-transactions 在Django 1.6中似乎已损坏。现在我的设置如下:

So, I've solved it using django-transaction-hooks. It still looks kinda scary to replace my DB backend, but django-celery-transactions seems to be broken in Django 1.6. Now my setup looks like this:

settings.py:

settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'transaction_hooks.backends.postgresql_psycopg2',
        'NAME': 'foo',
        },
    }
SOUTH_DATABASE_ADAPTERS = {'default':'south.db.postgresql_psycopg2'}  # this is required, or South breaks

models.py:

models.py:

from django.db import connection

@shared_task
def my_task(track):
    print 'in the task', track.id, track.points.all().count()

def some_method():
    t = Track()
    t.save()
    t = fill_with_points(t)  # creating points, attaching them to a Track
    t.save()
    print 'before the task', track.id, track.points.all().count()
    connection.on_commit(lambda: my_task.delay(t))

结果:

before the task, 21346, 2971
in the task, 21346, 2971

如此常见的用例没有本机celery或Django解决方案仍然令人感到奇怪。

It still seems strange that such a common use case has no native celery or Django solution.

这篇关于芹菜任务中缺少与Django相关的对象(竞赛条件?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆