我正在编写一个 Flask 应用程序,其中包含另外三个应用程序!管理员、经理和工人。 这三个在项目文件夹中有自己的文件夹。还有 app.py,它聚集了三个应用程序,以及 run.py,它运行最终的 Flask 应用程序。 但每当我尝试运行 run.py 时,都会出现错误:无法从部分初始化的模块“app”导入名称“db”
这是我刚刚写的app.py:
# app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# in-project imports
from config import Config, DB_NAME
from admin_app import create_admin_app
from manager_app import create_manager_app
from worker_app import create_worker_app
db = SQLAlchemy()
def create_app():
# Creates the application
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
from admin_app.models import Admin
from manager_app.models import Manager
from worker_app.models import Worker, Report
# Register Blueprints:
create_admin_app(app)
create_manager_app(app)
create_worker_app(app)
return app
这是完整的引用错误:
File "C:\Users\user\Desktop\Shortcuts\3-Other Courses\Flask-Projects\Manager\run.py", line 1, in <module>
from app import create_app
File "C:\Users\user\Desktop\Shortcuts\3-Other Courses\Flask-Projects\Manager\app.py", line 6, in <module>
from admin_app import create_admin_app
File "C:\Users\user\Desktop\Shortcuts\3-Other Courses\Flask-Projects\Manager\admin_app\__init__.py", line 3, in <module>
from .models import Admin
File "C:\Users\user\Desktop\Shortcuts\3-Other Courses\Flask-Projects\Manager\admin_app\models.py", line 1, in <module>
from app import db
ImportError: cannot import name 'db' from partially initialized module 'app' (most likely due to a circular import) (C:\Users\user\Desktop\Shortcuts\3-Other Courses\Flask-Projects\Manager\app.py)
这是引用中提到的文件:
# __init__.py
from flask import Blueprint
from flask_login import LoginManager
from .models import Admin
admin = Blueprint('admin', __name__, template_folder='templates', static_folder='static')
login_manager = LoginManager()
login_manager.login_view = 'admin.login'
@login_manager.user_loader
def load_user(user_id):
return Admin.query.get(user_id)
def create_admin_app(app):
login_manager.init_app(app)
app.register_blueprint(admin, url_prefix='/admin')
# models.py
from app import db
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
class Admin(db.Model, UserMixin):
__tablename__ = 'admin'
id = db.Column(db.Integer, primary_key=True)
personel_id = db.Column(db.Integer, nullable=False, unique=True)
password = db.Column(db.String(250), nullable=False)
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password, password)
def get_by_id(cls, user_id):
return cls.query.filter_by(personel_id=user_id).first()
您遇到的情况是
circular dependency
在 Flask 应用程序中并不罕见。当两个或多个模块相互依赖时,就会发生循环导入,导致 Python 无法正确初始化模块。
我想这就是它发生的原因
在您的情况下,发生循环导入是因为:
app.py
-> 从 admin_app 导入 create_admin_app。
admin_app/__init__.py
-> 从 admin_app/models.py 导入 Admin。
admin_app/models.py
-> 从 app.py 导入数据库。
你可以这样做
admin_app/models.py
以仅在需要时导入 db
。这里有一个代码片段来指导您
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Config, DB_NAME
from admin_app import create_admin_app
from manager_app import create_manager_app
from worker_app import create_worker_app
db = SQLAlchemy()
def create_app():
# Creates the application
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
# Import models only after db has been initializied
from admin_app.models import Admin
from manager_app.models import Manager
from worker_app.models import Worker, Report
# all Blueprints:
admin_app(app)
manager_app(app)
worker_app(app)
return app
或
Flask
根据此处找到的 Flask 文档:docs
“Flask 通过应用程序上下文解决了这个问题。您可以使用 current_app 代理,而不是直接引用应用程序,它指向处理当前活动的应用程序。Flask 在处理请求时自动推送应用程序上下文。”
这里有一个代码片段来指导您
admin_app/models.py
from flask import current_app
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
class Admin(UserMixin):
__tablename__ = 'admin'
id = db.Column(.... your columns here in your db)
personel_id = db.Column(.... your columns here in your db)
password = db.Column(.... your columns here in your db`)
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password, password)
def get_by_id(cls, user_id):
return cls.query.filter_by(personel_id=user_id).first()
@property
def db(self):
return current_app.extensions['sqlalchemy'].db