【发布时间】:2018-12-27 20:12:52
【问题描述】:
我想创建一个后台任务来更新特定日期的记录。我将 Django 和 Celery 与 RabbitMQ 一起使用。
我已经设法在使用这个虚拟任务函数保存模型时调用任务:
tasks.py
from __future__ import absolute_import
from celery import Celery
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
app = Celery('tasks', broker='amqp://localhost//')
@app.task(name='news.tasks.update_news_status')
def update_news_status(news_id):
# (I pass the news id and return it, nothing complicated about it)
return news_id
这个任务是从我的 models.py
中的 save() 方法调用的from django.db import models
from celery import current_app
class News(models.model):
(...)
def save(self, *args, **kwargs):
current_app.send_task('news.tasks.update_news_status', args=(self.id,))
super(News, self).save(*args, **kwargs)
事情是我想在tasks.py中导入我的新闻模型,但如果我尝试这样:
from .models import News
我收到此错误:
django.core.exceptions.ImproperlyConfigured:请求的设置 DEFAULT_INDEX_TABLESPACE,但未配置设置。你必须 要么定义环境变量 DJANGO_SETTINGS_MODULE 要么调用 settings.configure() 在访问设置之前。
这就是 mi celery.py 的样子
from __future__ import absolute_import, unicode_literals
from celery import Celery
import os
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
app = Celery('myapp')
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
我已经试过了:
- can't import django model into celery task
- 我已尝试在任务方法Django and Celery, AppRegisteredNotReady exception 中进行导入
- 我也试过这个Celery - importing models in tasks.py
- 我也尝试创建一个 utils.py 并将其导入,但不可行。
遇到了不同的错误,但最后我无法在 tasks.py 中导入任何模块
我的配置可能有问题但我看不到错误,我按照The Celery Docs: First steps with Django中的步骤操作
另外,我的项目结构是这样的:
├── myapp
│ ├── __init__.py
├── ├── celery.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── news
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── tasks.py
│ ├── urls.py
│ ├── models.py
│ ├── views.py
├── manage.py
我正在像这样从myapp 目录执行工作人员:
celery -A news.tasks worker --loglevel=info
我在这里缺少什么?提前感谢您的帮助!
lambda:settings.INSTALLED_APPS
编辑
在 cmets 中进行建议的更改后:
将此添加到 celery.py
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
并导入内部方法:tasks.py
from __future__ import absolute_import
from celery import Celery
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
app = Celery('tasks', broker='amqp://localhost//')
@app.task(name='news.tasks.update_news_status')
def update_news_status(news_id):
from .models import News
return news_id
我收到以下错误:
[2018-07-20 12:24:29,337: ERROR/ForkPoolWorker-1] Task news.tasks.update_news_status[87f9ec92-c260-4ee9-a3bc-5f684c819f79] raised unexpected: ValueError('Attempted relative import in non-package',)
Traceback (most recent call last):
File "/Users/carla/Develop/App/backend/myapp-venv/lib/python2.7/site-packages/celery/app/trace.py", line 382, in trace_task
R = retval = fun(*args, **kwargs)
File "/Users/carla/Develop/App/backend/myapp-venv/lib/python2.7/site-packages/celery/app/trace.py", line 641, in __protected_call__
return self.run(*args, **kwargs)
File "/Users/carla/Develop/App/backend/news/tasks.py", line 12, in update_news_status
from .models import News
ValueError: Attempted relative import in non-package
【问题讨论】:
-
你能用这个app吗.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 什么是芹菜版本>>>???
-
嗨@HemanthSP 添加这不起作用。 Celery 版本是 4.2.1
-
你可以试试 celery -A news worker -l info,你的代码在 redis 上运行良好。并尝试将 task.py 中的每个代码移动到 celery.py 并再次检查
-
此处显示的代码有效,我无法实现的是将 News 模型导入 tasks.py @HemanthSP
-
您的错误来自 django 或 celery 终端?
标签: python django celery python-import