[英]Flask ImportError: cannot import name (for app in __init__.py)
[英]Flask - Cannot use instance celery into app/__init__.py?
我已经访问了社区中的几个问题,但我认为这是我的错,因为我无法确定一个合适的方法,在使用 Flask 文档中指出的工厂架构模式。
我们有一个基于Flask + Gunicorn + Nginx的应用程序,它总是在没有重大挑战的情况下工作。 但是,我们需要构建一个需要异步任务的解决方案。 很快,指示一致,为此使用 Celery,但甚至遵循此处使用的样式。
我无法编译项目,因为它通知存在导入错误,并且框架的官方文档并没有明确说明如何在结构工厂中使用它,只是如何在单个实例中进行操作。
我该如何解决这个问题?
我的追溯:
File "/home/user/Workspace/test/project_async/celery_runner.py", line 3, in <module>
from app import create_app
File "/home/user/Workspace/test/project_async/app/__init__.py", line 9, in <module>
from .api import configure as config_api
File "/home/user/Workspace/test/project_async/app/api.py", line 3, in <module>
from .resources.chosen import Change
File "/home/user/Workspace/test/project_async/app/resources/chosen.py", line 5, in <module>
from app.jobs.tasks import exec_change as tk_change
File "/home/user/Workspace/test/project_async/app/jobs/tasks.py", line 1, in <module>
from app import celery
ImportError: cannot import name 'celery' from 'app' (/home/user/Workspace/test/project_async/app/__init__.py)
我的结构:
.
├── app
│ ├── api.py
│ ├── jobs
│ │ ├── celeryconfig.py
│ │ ├── __init__.py
│ │ └── tasks.py
│ ├── jwt.py
│ ├── models
│ │ ├── core.py
│ │ ├── __init__.py
│ │ ├── inventory.py
│ │ └── other.py
│ ├── resources
│ │ ├── chosen.py
│ │ └── __init__.py
│ ├── schemas.py
│ ├── services
│ │ ├── chosen.py
│ │ ├── base.py
│ │ ├── chosen_other.py
│ │ └── inventory.py
│ ├── static
│ │ ├── swagger.json
│ │ └── swagger.yaml
│ ├── swagger.py
│ └── utils.py
├── celery_runner.py
├── config.py
├── main.py
├── test.log
└── tests
├── __init__.py
└── test_inventory.py
代码:
路径 - app/__init__.py
from flask import Flask
from flask_cors import CORS
from flask_migrate import Migrate
from config import configure as config_project
from .api import configure as config_api
from .jwt import configure as config_jwt
from .models.core import configure as config_db
from .models.inventory import configure as config_db_mongo
from .swagger import configure as config_docs
from celery import Celery
celery = Celery(__name__)
def create_app(config_name):
app = Flask(__name__)
'''Added Configurations'''
config_project(app)
config_jwt(app)
config_api(app)
config_docs(app)
config_db(app)
config_db_mongo(app)
'''Added Thirds'''
CORS(app)
Migrate(app, app.db)
'''Background Tasks'''
celery.conf.update(app.config)
celery.config_from_object('app.jobs.celeryconfig')
return app
路径 - project_async/celery_worker.py
from dotenv import find_dotenv, load_dotenv
from app import create_app
load_dotenv(find_dotenv())
app = create_app(getenv('FLASK_ENV') or 'default')
app.app_context().push()
路径 - app/jobs/celeryconfig.py
broker_url = 'redis://localhost:6379/1'
result_backend = 'redis://localhost:6379/0'
# import
imports = 'app.jobs.tasks'
# Timezone
timezone = 'America/Bogota'
enable_utc = True
路径 - app/jobs/tasks.py
from app import celery
from app.services.chosen_other import ChangeOpportunity
@celery.task(name='tasks.change')
def exec_change(data, change, client):
change = ChangeOpportunity(data, change, client)
change.execute_change()
这是由循环导入引起的。 实际问题是导入api.py
最终会导入您的 Celery 任务。 由于您在定义celery
实例之前执行from .api import configure
,这打破了循环依赖。
您应该尝试重新组织您的代码,以便导入一个模块时不需要导入许多其他模块。 如果您查看堆栈跟踪,您可以看到api.py
导入了resources/chosen.py
,它导入了jobs/tasks.py
。 是否需要所有交叉包导入?
尝试分解更复杂的模块,以便您没有所有这些间接导入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.