2016-11-06 4 views
2

Я пытаюсь запустить некоторые фоновые задания, используя Celery + Redis + Flask.ImportError: не может импортировать имя сельдерей

Моя структура приложение:

myapp/ 
    celery_worker.py 
    manage.py 
    myapp/ 
    __init__.py 
    app.py 
    bot/ 
     __init__.py 
     tasks.py 
    accounts/ 
     views.py 

I инициализируется сельдерей в app.py как:

celery = Celery('tasks', include=['bot.tasks']) 

def create_app(config=None, app_name=None, blueprints=None): 
    # more Celery and other config here like celery.conf.update() 

И начать рабочий по celery_worker.py

from myapp import create_app, celery 

app = create_app() 
app.app_context().push() 

tasks.py содержит

from myapp import celery 

@celery.task(name='my_task_bot') 
def my_task_bot(): 
    # pass 

Теперь, когда я пытаюсь получить доступ задач из tasks.py в бухгалтерии/views.py с импортируют:

from ..bot.tasks import my_task_bot 

Я получаю ImportError: cannot import name celery ошибку.

Независимо от того, где я пытаюсь импортировать задачи, я получаю эту ошибку. Этот экземпляр celery представляется тем, который инициализируется в app.py, но не импортируется.

PS: Я следую схеме https://github.com/ezequielo/flask_celery_exp репо, и он отлично работает. Но не мое приложение.

Edit:

Вот Traceback:

Traceback (most recent call last): 
    File "manage.py", line 8, in <module> 
    from myapp import create_app 
    File "/home/mars/myapp/myapp/__init__.py", line 3, in <module> 
    from app import create_app, celery 
    File "/home/mars/myapp/myapp/app.py", line 18, in <module> 
    from .accounts import (accounts, AccountsAdmin) 
    File "/home/mars/myapp/myapp/accounts/__init__.py", line 7, in <module> 
    from .views import accounts 
    File "/home/mars/myapp/myapp/accounts/views.py", line 6, in <module> 
    from ..bot.tasks import my_task_bot 
    File "/home/mars/myapp/myapp/bot/tasks.py", line 14, in <module> 
    from myapp import celery 
ImportError: cannot import name celery 

Fatal error: local() encountered an error (return code 1) while executing 'python manage.py initdb' 

Я получаю вышеуказанную ошибку при попытке запустить любой из любой manage.py или celery_worker.

Просьба предложить.

ответ

3

Ваша логика импорта не является правильным и приводит к круговой зависимости. Не инициализируйте сельдерей в app.py вместе со ссылкой на модуль (accounts), который, в свою очередь, импортирует экземпляр celery.

У вас есть несколько вариантов:

  1. удаления зависимости от приложения accounts в app.py модуля

  2. Положите сельдерей объект инициализации в общий модуль, который не относится к любым другим модулям, но отнесено /*/tasks.py подмодулей.

  3. Не импортируйте сельдерей в задачи, но используйте shared_task декоратор.Для получения дополнительной информации обратитесь к doc

Важен: Не забудьте соответствующую ссылку сельдерея приложение к вашему @shared_tasks. Приложение Celery должно быть загружено перед любой задачей. По этой причине определите инициализацию сельдерея в celery.py, а затем загрузите его на myapp/__init__.py.

from __future__ import absolute_import 

from .celery import app as celery_app # noqa 

В качестве альтернативы вы можете подробнее рассказать об этом link. Он показывает хороший способ организации вашего фляга вместе с приложением для сельдерея.

+0

Третий вариант работал как шарм. Благодаря! – nml

+0

сейчас, я получаю 'socket.error: [Errno 111] Connection reject' error при попытке запуска задач из флеш-приложения. это связано с @shared_task? как в документации упоминается, что этот декоратор создает задачи без какого-либо конкретного экземпляра. – nml

+0

Никакой документ celery doc не означает, что «Декоратор @shared_task позволяет создавать задачи, которые могут использоваться любыми приложениями». Я использую его следующим образом в пирамиде, колбе, джанго. Не могли бы вы предоставить более подробную информацию? Какой брокер вы используете? если redis, уверен, что он работает? Было бы лучше, если вы предоставите детали конфигурации. –

2

tasks.py

from myapp.app import celery 

https://docs.python.org/3.5/tutorial/modules.html#packages

+0

уже пытались выше, но все еще получаю ту же 'ImportError '. Я обновил trackback в оригинальном вопросе. Видеть, что. – nml

+0

true, см. Мой ответ –

+0

Я вижу. Это означает, что ваша задача загружается до приложения сельдерея, а затем нет правильной связи между shared_task и вашим приложением для сельдерея. Вы можете попробовать импортировать сельдерей в модуль 'myapp .__ init__': –

1

В файле, который вы инициализируете Сельдерей, добавьте это как первую строку.

from __future__ import absolute_import 

Объяснение

from __future__ import absolute_import означает, что, если импортировать сельдерей, Python будет искать модуль сельдерея верхнего уровня, а не current_package.celery. Это должно помочь исправить ошибку, которую вы получаете. Но убедитесь, что сельдерей установлен на . Хорошо, что сельдерей должен быть установлен. Это работает для питона версии позже, чем 2.6

0

я разрешить эту ошибку снимите флажок «добавить корни контента в пути питона» и «добавить soruce корни в пути питона» в PyCharm

Смежные вопросы