[英]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.