ImportError: cannot import name 'db' from [package_name]

ImportError: cannot import name 'db' from [package_name]

我的代码结构很复杂。项目文件夹有一个包含两个子包的母包。我需要从母包的 init.py 文件导入一个 SQLAlchemy 实例,db 到子包 db_models.py 文件。 db_models.py 包含交换对数据库的调用的所有路由。我看到了其他解决方案,但这些解决方案并没有解决问题,因为我有多个包。以下是我的项目的层次结构。

FlaskUserAuthentication(project)
    FlaskUserAuthentication(package)=>
        API(package)=>
            __init__.py
            db_models.py
            routes.py(Blueprint)
        Site(package)=>
            __init__.py
            routes.py(Blueprint)
            templates=>
                index.html
                signin.html
                signup.html
        __init__.py
run.py (under project)

在项目文件夹FlaskUserAuthentication下,我有一个同名的package(FlaskUserAuthentication)。以下是其 __init__.py 文件中的代码。

from flask import Flask
from FlaskUserAuthentication.API.routes import api
from FlaskUserAuthentication.Site.routes import site
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'

app.register_blueprint(api)
app.register_blueprint(site)

APISite 下的两个子包下,有 routes.py 个文件,其中一个处理数据库查询(API/routes.py),另一个一个渲染视图(Site/routes.py)。这两个包都有一个蓝图实例。

以下是来自API(package)/routes.py文件的代码-

from flask import jsonify, Blueprint, request
from FlaskUserAuthentication.API.db_models import Member

api = Blueprint('api', __name__)

@api.route('/members')
def get_all_members():
    members = Member.query.all()
    return jsonify({'response': 'This will return the members from the sqlite database'})

但是在第二行,我试图导入 SQLAlchemy 模型 class、Member,我收到了一些错误,该错误不涉及该行,但是在我添加那行之前没关系,所以我意识到就是这样。以下是我收到的错误 -

Traceback (most recent call last):
  File "F:\FlaskUserAuthentication\run.py", line 1, in <module>
    from FlaskUserAuthentication import app
  File "F:\FlaskUserAuthentication\FlaskUserAuthentication\__init__.py", line 2, in <module>
    from FlaskUserAuthentication.API.routes import api
  File "F:\FlaskUserAuthentication\FlaskUserAuthentication\API\routes.py", line 2, in <module>
    from FlaskUserAuthentication.API.db_models import Member
  File "F:\FlaskUserAuthentication\FlaskUserAuthentication\API\db_models.py", line 1, in <module>
    from FlaskUserAuthentication import db
ImportError: cannot import name 'db' from 'FlaskUserAuthentication' (F:\FlaskUserAuthentication\FlaskUserAuthentication\__init__.py)

以下代码来自API/db_model.py文件-

from FlaskUserAuthentication import db
from datetime import datetime

class Member(db.Model):
    id = db.Column('id', db.Integer, primary_key=True)
    username = db.Column('user_name', db.String(100), nullable=False)
    email = db.Column('email', db.String(100), nullable=False, unique=True)
    password = db.Column('password', db.String(100), nullable=False, unique=False)

但是,如果我在 API/routes.py 文件下注释掉 from FlaskUserAuthentication.API.db_models import Member,我不会收到此错误。

我意识到这一定是循环导入问题,但谁能解释一下如何避免此类错误?

如何在我的 routes.py 文件中导入我的 db_model classes?

您似乎在 db(在 API/db_model.py 中)初始化之前导入它。快速而肮脏的解决方案可能是在 __init__.py.

中初始化 db 对象后 api 导入
from flask import Flask
from FlaskUserAuthentication.Site.routes import site
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'

from FlaskUserAuthentication.API.routes import api

我建议您使用应用工厂模式,但是,随着您的应用程序变得越来越复杂。