导入 flask-SQLAlchemy 模型时出现 AttributeError

AttributeError when importing flask-SQLAlchemy model

我正在按照 this 教程构建基于 JWT 的身份验证系统。

app.py:

from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'd0cad49580952003e6ae01499c7bb190a4b4f9a5babd866f47064707f7b78506'

api = Api(app)
db = SQLAlchemy(app)


@app.before_first_request
def create_tables():
    db.create_all()


import resources, models

api.add_resource(resources.UserRegistration, '/registration')


if __name__ == '__main__':
    app.run()

models.py:

from app import db


class UserModel(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(150), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)

    def __init__(self, name, password, email):
        self.name = name
        self.password = password
        self.email = email

    @classmethod
    def find_by_username(cls, username):
        return cls.query.filter_by(username=username).first()

    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

resources.py:

from flask_restful import Resource, reqparse
from models import UserModel


class UserRegistration(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name', help='This field cannot be blank', required=True)
        parser.add_argument('email', help='This field cannot be blank', required=True)
        parser.add_argument('password', help='This field cannot be blank', required=True)

        data = parser.parse_args()

        if UserModel.find_by_username(data['name']):
            return {'message': 'User {} already exists'.format(data['name'])}

        new_user = UserModel(
            name=data['name'],
            password=data['password'],
            email=data['email']
        )
        try:
            new_user.save_to_db()
            return {
                'status': 'User {} was created'.format(data['username'])}

        except:
            return {'message': 'Something went wrong'}, 500

当我 运行 app.py 时,出现以下错误:

Traceback (most recent call last):
  File "G:\python\PycharmProjects\vumonic\app.py", line 19, in <module>
    import resources, models
  File "G:\python\PycharmProjects\vumonic\resources.py", line 2, in <module>
    from models import UserModel
  File "G:\python\PycharmProjects\vumonic\models.py", line 1, in <module>
    from app import db
  File "G:\python\PycharmProjects\vumonic\app.py", line 21, in <module>
    api.add_resource(resources.UserRegistration, '/registration')
AttributeError: module 'resources' has no attribute 'UserRegistration'

当我从 resources.py 中删除 from models import UserModel 时,此错误消失了。

我无法找出错误的原因。

我正在使用 Flask==1.1.2、Flask-SQLAlchemy==2.4.4 和 Flask-RESTful==0.3.8

这是我第一次开发 API,如有任何帮助,我们将不胜感激。

您遇到循环导入问题。

当Python 导入模块时,它会检查模块注册表以查看该模块是否已导入。如果模块已经注册,Python 使用缓存中的现有对象。模块注册表是 table 已按模块名称初始化和索引的模块。这个table可以通过sys.modules访问。

如果未注册,Python 查找模块,必要时初始化它,并在新模块的命名空间中执行它。

要了解有关循环导入的更多信息,您可以阅读文章:

https://stackabuse.com/python-circular-imports/

https://www.stefaanlippens.net/circular-imports-type-hints-python.html

Miguel Grinberg 的这个教程是救星 https://www.youtube.com/watch?v=NH-8oLHUyDc&t=3205s