You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次搭建Flask工厂模式遇ImportError:循环导入致无法导入db

解决Flask工厂模式下的循环导入错误

错误信息

Traceback (most recent call last):
  File "/Users/grahammorby/Documents/GitHub/tagr-api/venv/lib/python3.12/site-packages/flask/cli.py", line 219, in locate_app
    __import__(module_name)
  File "/Users/grahammorby/Documents/GitHub/tagr-api/wsgi.py", line 1, in <module>
    from application import init_app
  File "/Users/grahammorby/Documents/GitHub/tagr-api/application/__init__.py", line 9, in <module>
    from application.users import users_blueprint
  File "/Users/grahammorby/Documents/GitHub/tagr-api/application/users.py", line 3, in <module>
    from application.models import User
  File "/Users/grahammorby/Documents/GitHub/tagr-api/application/models.py", line 2, in <module>
    from . import db, ma
ImportError: cannot import name 'db' from partially initialized module 'application' (most likely due to a circular import) (/Users/grahammorby/Documents/GitHub/tagr-api/application/__init__.py)

项目文件内容

wsgi.py

from application import init_app

app = init_app()

if __name__ == "__main__":
    app.run(host='0.0.0.0')

初始版本 application/__init__.py

from flask import Flask
from config import Config

from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager

from application.users import users_blueprint
from application.apps import apps_blueprint

# Globally accessible libraries
db = SQLAlchemy()
ma = Marshmallow()
bcrypt = Bcrypt()
JWTManager = JWTManager()


def init_app():
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object(Config)

    # Setup plugins
    db.init_app(app)
    ma.init_app(app)
    bcrypt.init_app(app)
    JWTManager.init_app(app)

    with app.app_context():
        # Blueprints
        return app

application/models.py

from sqlalchemy import Column, Integer, String
from . import db, ma

class App(db.model):
    __tablename__ = "apps"
    id = Column(Integer, primary_key=True)
    app_name = Column(String(64))
    icon = Column(String(255))


class AppSchema(ma.Schema):
    class Meta:
        fields = ("id", "app_name", "icon")


app_schema = AppSchema()
apps_schema = AppSchema(many=True)

修改后仍有问题的 application/__init__.py

def init_app():
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object(Config)

    # Setup plugins
    db.init_app(app)
    ma.init_app(app)
    bcrypt.init_app(app)
    JWTManager.init_app(app)
    Migrate = init_app(app, db)

    from models import User, App

    with app.app_context():
        # Blueprints
        from application.users import users_blueprint
        from application.apps import apps_blueprint

        app.register_blueprint(users_blueprint)
        app.register_blueprint(apps_blueprint)

        return app

解决方案

核心问题

循环导入的根源是模块级导入顺序冲突:__init__.py在模块顶部导入蓝图,蓝图依赖models.py,而models.py需要导入__init__.py中尚未完成定义的db/ma实例,导致模块初始化卡住。

具体修复步骤

  1. 调整导入位置,避免模块级循环
    将蓝图、models的导入从__init__.py的模块顶部,移到init_app函数内部,且放在插件初始化之后、app上下文环境中。确保db/ma等实例完全初始化后,再导入依赖它们的模块。

  2. 修正models.py的笔误
    将class App(db.model):改为class App(db.Model):(注意Model首字母大写),否则会触发属性不存在的错误。

  3. 规范插件实例命名
    不要用插件类名作为实例变量名(如原代码中的JWTManager = JWTManager()),避免命名冲突,改为jwt = JWTManager()。

修正后的代码

application/__init__.py

from flask import Flask
from config import Config

from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager
from flask_migrate import Migrate

# 仅在模块级别定义插件实例,不导入内部模块
db = SQLAlchemy()
ma = Marshmallow()
bcrypt = Bcrypt()
jwt = JWTManager()
migrate = Migrate()

def init_app():
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object(Config)

    # 初始化所有插件
    db.init_app(app)
    ma.init_app(app)
    bcrypt.init_app(app)
    jwt.init_app(app)
    migrate.init_app(app, db)

    with app.app_context():
        # 先导入models,确保db已初始化
        from application import models
        # 再导入并注册蓝图
        from application.users import users_blueprint
        from application.apps import apps_blueprint

        app.register_blueprint(users_blueprint)
        app.register_blueprint(apps_blueprint)

        return app

application/models.py

from sqlalchemy import Column, Integer, String
from . import db, ma

class App(db.Model):
    __tablename__ = "apps"
    id = Column(Integer, primary_key=True)
    app_name = Column(String(64))
    icon = Column(String(255))

class AppSchema(ma.Schema):
    class Meta:
        fields = ("id", "app_name", "icon")

app_schema = AppSchema()
apps_schema = AppSchema(many=True)

验证修复

启动应用后,循环导入错误会消失,同时models中的笔误也被修正,确保数据库模型能正常工作。

内容的提问来源于stack exchange,提问作者Graham Morby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:35:54