[英]Celery Result error “args must be a list or tuple”
I am running a Django website and have just gotten Celery to run, but I am getting confusing errors. 我正在运行一个Django网站并且刚刚让Celery运行,但是我遇到了令人困惑的错误。 Here is how the code is structured.
以下是代码的结构。
In tests.py: 在tests.py中:
from tasks import *
from celery.result import AsyncResult
project = Project.objects.create()
# initalize various sub-objects of the project
c = function.delay(project.id)
r = AsyncResult(c.id).ready()
f = AsyncResult(c.id).failed()
# wait until the task is done
while not r and not f:
r = AsyncResult(c.id).ready()
f = AsyncResult(c.id).failed()
self.assertEqual() #will fail because task fails
in tasks.py: 在tasks.py中:
from __future__ import absolute_import
from celery import shared_task
@shared_task
def function(project_id)
#a bunch of calculations followed by a save of the project
project = Project.objects.get(project=project_id)
for part in project.part_set.all():
partFunction(part.id)
p = Part.objects.get(id=part.id)
# add to various variables in project from variables in p
project.save()
in mainapp/settings.py: 在mainapp / settings.py中:
BROKER_URL = "amqp://ipaddress"
CELERY_RESULT_BACKEND='amqp'
CELERY_ACCEPT_CONTENT = ['json','pickle','msgpack','yaml']
CELERY_IGNORE_RESULT = False
the celery debug console log for must by list/tuple: celery调试控制台日志必须通过list / tuple:
[INFO/MainProcess] Received task: myapp.tasks.function[id]
[ERROR/MainProcess] Task myapp.tasks.function[id]
raised unexpected: ValueError('task args must be a list or tuple',)
Traceback:
File "/python2.7/site-packages/celery/app/trace.py", line 240, in trace_task
R = retval = fun(*args, **kwargs)
File "/python2.7/site-packages/celery/app/trace.py", line 437, in __protected_call__
return self.run(*args, **kwargs)
File "/myapp/tasks.py", line 28, in function
p = Part.objects.get(id=part.id)
File "/python2.7/site-packages/celery/app/task.py", line 555, in apply_async
**dict(self._get_exec_options(), **options)
File "/python2.7/site-packages/celery/app/base.py", line 351, in send_task
reply_to=reply_to or self.oid, **options
File "celery/app/amqp.py", line 252, in publish_task
raise ValueError('task args must be a list or tuple')
ValueError: task args must be a list or tuple
the error I am getting is as above, AsyncResult(c.id).result: task args must be a list or tuple
. 我得到的错误如上所述,
AsyncResult(c.id).result: task args must be a list or tuple
。 This should be an easy solution but it is not. 这应该是一个简单的解决方案,但事实并非如此。 When I make it a list like so:
当我把它变成这样的列表时:
inline = [project.id]
c = function.delay(inline)
It then changes it mind and tells me that AsyncResult(c.id).result: int() argument must be a string or a number, not 'list'
然后它改变了主意并告诉我
AsyncResult(c.id).result: int() argument must be a string or a number, not 'list'
As you can imagine I am very confused as to what might be the problem. 你可以想象我对可能出现的问题非常困惑。
tasks.py tasks.py
@shared_task
def function(app):
@app.task(name='myapp.function', bind=True)
def function(project_id):
tests.py tests.py
c = function.s(project.id).delay()
function.app prints function.app打印
You are getting an error in your code inside the task, it shows in traceback: 您在任务中的代码中收到错误,它在回溯中显示:
File "/myapp/tasks.py", line 28, in function
p = Part.objects.get(id=part.id)
Your code seems right, but from the traceback it looks like celery has an old version of task pickled. 你的代码似乎是正确的,但从追溯看起来,芹菜有一个旧版本的任务腌制。 Very important that you restart celery whenever you change anything inside
task.py
(maybe even if you change other files, but I don't think so). 非常重要的是,每当你在
task.py
更改任何内容时重启芹菜(可能即使你更改了其他文件,但我不这么认为)。 It could be a cause of your problem, it bit me in a butt couple of times. 这可能是你问题的原因,它让我陷入困境几次。
Also there is no reason to pull the part
from database individually p = Part.objects.get(id=part.id)
since you already getting current part instance when you are iterating over a queryset in for part in project.part_set.all():
. 此外,没有理由单独从数据库中提取
part
p = Part.objects.get(id=part.id)
因为当您for part in project.part_set.all():
中for part in project.part_set.all():
迭代查询集时,您已经获得了当前部件实例for part in project.part_set.all():
This one is just a suggestion, you might have more code that needs that step. 这只是一个建议,你可能有更多的代码需要这一步。
As a side note, if it is a task in your project and not a part of some reusable app, just use a regular @task
decorator, celery will find it, but make sure you configure Celery
app right, here is another one of my posts that can guide you through: Celery / Django Single Tasks being run multiple times 作为旁注,如果它是您项目中的任务而不是某些可重用应用程序的一部分,只需使用常规的
@task
装饰器,芹菜就会找到它,但请确保您正确配置Celery
应用程序,这是我的另一个可以指导您完成的帖子: Celery / Django Single Tasks被多次运行
So as long as you have everything configured correctly, just use it as you did before: 因此,只要您正确配置了所有内容,就像以前一样使用它:
@task #or @shared_task
def function(project_id)
#a bunch of calculations followed by a save of the project
project = Project.objects.get(project=project_id)
....
Then call it: 然后叫它:
result = function.delay(project.id)
or: 要么:
result = function.apply_async(args=(project.id,))
Obviously I'd also recommend testing the task directly by calling it without celery function(project.id)
, but I'm sure you knew that. 显然我还建议直接通过调用没有celery
function(project.id)
测试任务,但我相信你知道的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.