我在 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% 的把握这不会是问题,但我认为最好检查以确保。如果我使用单一的大规模方法没有区别。