简体   繁体   English

我怎么能将一个大的django-celery tasks.py模块拆分成更小的块?

[英]how can i split up a large django-celery tasks.py module into smaller chunks?

I have some very lengthy task functions that I would like to break out from my tasks.py module, but still be able to call like from myapp.tasks import my_task . 我有一些非常冗长的任务函数,我想从我的tasks.py模块中分离出来,但仍然能够像from myapp.tasks import my_task一样调用。 I tried creating submodules for each task, but then I have to insert some trickery into tasks/__init__.py , which seems pretty hackish (and requires giving the tasks the same names as the modules): 我尝试为每个任务创建子模块,但后来我必须在tasks/__init__.py一些tasks/__init__.py ,这看起来非常h​​ackish(并且需要赋予任务与模块相同的名称):

import pkgutil

for module_loader, name, ispkg in pkgutil.iter_modules(__path__):
    __import__('myapp.tasks.%s' % name)
    locals().update({name: getattr(locals()[name], name)})

This answer is about management commands rather than tasks in the sense of Celery background tasks. 这个答案是关于管理命令而不是Celery后台任务意义上的任务。


I think the most straight-forward solution is to first write the tasks as Django management commands, and then call those from tasks.py. 我认为最直接的解决方案是首先将任务编写为Django管理命令,然后从tasks.py中调用它们。 This way you can break up your tasks into one task per file, and have the additional benefit of being able to call your tasks arbitrarily from the command line. 这样,您可以将每个文件的任务分解为一个任务,并具有能够从命令行任意调用任务的额外好处。

So, in tasks.py : 所以,在tasks.py

from django.core import management

@task()
def my_task():
    management.call_command('my_task')

I'm not familiar with Django-Celery but quite familiar with Celery, so this is more of a general note which may answer your question... 我不熟悉Django-Celery,但对Celery非常熟悉,所以这更像是一个可以回答你问题的一般性说明......

Celery tasks are identified by name when executed. Celery任务在执行时按名称标识。 By default, tasks are given the name of their Python location, ie. 默认情况下,任务被赋予其Python位置的名称,即。 '%s.%s' % (my_task.__module__, my_task.__name__) , or 'myapp.tasks.function_name'. '%s.%s' % (my_task.__module__, my_task.__name__)或'myapp.tasks.function_name'。 That said, you can override the task name by supplying the @task decorator with the 'name' kwarg. 也就是说,您可以通过向@task装饰器提供'name'kwarg来覆盖任务名称。 So if you wanted to override a task name: 因此,如果您想覆盖任务名称:

# We're in myapp.tasks but the task will not be named myapp.tasks.my_task as expected
@task(name='some.overridden.name')
def my_task():
    print 'Something'

The following works as well: 以下工作原理:

  • create a package tasks 创建一个包tasks
  • spread your tasks in python modules inside the tasks package tasks包中的python模块中传播你的tasks
  • import the modules in the tasks/__init__.py 导入tasks/__init__.py的模块

Example: 例:

django_app
| tasks
   | __init__.py
   | filesystem_tasks.py
| admin.py
| url.py
  • tasks/filesystem_tasks.py can contain this: tasks/filesystem_tasks.py可以包含:

     from __future__ import absolute_import, unicode_literals from celery import shared_task @shared_task def add(x, y): return x + y 
  • tasks/__init__.py can contain this: tasks/__init__.py可以包含:

     from .filesystem_tasks import * 
  • Running celery indicates the tasks as they would have been declared in one tasks.py at the same level as eg. 运行芹菜表示任务,因为它们将在一个tasks.py中以与例如相同的级别声明。 url.py . url.py

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM