python - 导入flask-SQLAlchemy模型时出现AttributeError
问题描述
我正在按照本教程构建基于 JWT 的身份验证系统。
应用程序.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()
模型.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()
资源.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'
from models import UserModel
当我从 resources.py中删除时,此错误消失。
我无法弄清楚错误的原因。
我正在使用 Flask==1.1.2、Flask-SQLAlchemy==2.4.4 和 Flask-RESTful==0.3.8
这是我第一次开发 API,因此将不胜感激。
解决方案
您正面临循环导入问题。
当 Python 导入一个模块时,它会检查模块注册表以查看该模块是否已被导入。如果模块已经注册,Python 会使用缓存中的现有对象。模块注册表是一个已初始化并按模块名称索引的模块表。可以通过 访问该表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
推荐阅读
- visual-studio - SSIS 错误 - 由于 80040153、注册表值无效,从 SQL 任务中解析查询失败
- python-3.x - 如何在多线程中进行 Cassandra 插入?
- python - 非分类掩码的 UNet 损失函数?
- python - 如何在 Python 关键字/变量名中使用单引号?
- r - R闪亮的反应元件没有按预期反应
- listview - 在JavaFX中双击时如何编辑ListView项目?
- runtimeexception - RuntimeException - 原因不明
- ruby - 如何安装 PostgreSQL:错误:无法构建 gem 原生扩展
- c# - MongoDb & C#:在大索引上使用带有排序的游标
- ios - Swift 看不到数据