如何处理“无法导入部分初始化的模块”错误消息?

问题描述 投票:0回答:1

我正在编写一个 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()
python flask
1个回答
0
投票

您遇到的情况是

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 导入数据库。

你可以这样做

  1. 将 db Import 移至您选择的命名函数内 修改
    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

  1. 上下文切换的使用
    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
© www.soinside.com 2019 - 2024. All rights reserved.