具有Celery和RabbitMQ的Python不能正常运行

时间:2013-08-28 19:23:15

标签: python django celery

我在Ubuntu 13.04上使用Django 1.4.3和Python 2.7,Celery 3.0.1和django-celery 3.0.17。

我有一些任务设置来运行耗时的进程。如果我将它们设置为与芹菜排队,则它们的行为不正常。如果我在不排队的情况下运行它们,一切都表现得很完美。关于为什么会出现这种情况的任何想法?

为我的问题提供一些动力。我需要克隆公司合同。每份合约都有多个与之相关的优惠。每个优惠都有多个优惠字段。每个商品字段都有多个值。我需要克隆一切。

这是我正在做的一个例子。

def clone_contract(self, contract_id, contract_name):
    old_contract = models.Contract.objects.get(pk=contract_id)
    contract_dict = dict()
    for attr in old_contract._meta.fields:
        contract_dict[attr.name] = getattr(old_contract, attr.name)
    del contract_dict['id']
    contract_dict['name'] = contract_name
    new_contract = contracts_models.Contract(**contract_dict)
    new_contract.save()
    contracts_tasks.clone_offers.delay(new_contract, old_contract)

@task(name='Clone Offers')
def clone_offers(new_contract, old_contract):
    for offer in old_contract.offer_set.all():
        offer_dict = dict()
        for attr in offer._meta.fields:
            offer_dict[attr.name] = getattr(offer, attr.name)
        del offer_dict['id']
        del offer_dict['contract']
        offer_dict['contract_id'] = new_contract.pk
        new_offer = contracts_models.Offer(**offer_dict)
        new_offer.save()
        clone_offer_fields(new_offer, offer)

def clone_offer_fields(new_offer, old_offer):
    offer_fields = models.OfferField.objects.filter(offer=old_offer)
    for offer_field in offer_fields:
        initial = dict()
        for attr in offer_field._meta.fields:
            initial[attr.name] = getattr(offer_field, attr.name)
        initial['offer'] = new_offer
        del initial['id']
        new_offer_field = contracts_models.OfferField(**initial)
        new_offer_field.save()
        model = models.OfferFieldValue
        values = model.objects.filter(**{'field': offer_field})
        clone_model(new_offer_field, model, 'field', values)

def clone_model(new_obj, model, fk_name, values):
    for value in values:
        initial = dict()
        for attr in value._meta.fields:
            initial[attr.name] = getattr(value, attr.name)
        del initial['id']
        initial[fk_name] = new_obj
        new_value = model(**initial)
        new_value.save()

从我观察到的clone_offers起作用但clone_offer_fields不起作用 - 只有当clone_offers被称为clone_offers.delay()时才会这样做。如果我在没有clone_offers的情况下运行此.delay()(不排队),一切都会完美无缺。

不幸的是我无法登录排队的任务(似乎没有写入日志文件)所以我无法在代码中进行故障排除。

在排队任务中调用函数是否存在问题?我很确定我之前没有遇到任何问题。 (编辑:下面回答)

任何建议都将不胜感激。

EDIT1: 我决定测试这个把所有的方法扔在一起。我99%肯定这不会是问题,但认为最好确定一下。如果我使用单一的大规模方法没有区别。

1 个答案:

答案 0 :(得分:0)

问题涉及Celery劫持默认日志记录。我实现了给出的解决方案:Django Celery Logging Best Practice