【问题标题】:How to avoid circular imports in a Flask app with Flask SQLAlchemy models?如何避免使用 Flask SQLAlchemy 模型在 Flask 应用程序中进行循环导入?
【发布时间】:2018-07-20 23:42:05
【问题描述】:

我正在进入 Flask 并构建一个使用 Flask SQLAlchemy 的应用程序。我创建了一个基本 API,当所有代码都在一个文件中时,它可以工作,但希望更好地组织它,如下所示:

app/models/user.py

from datetime import datetime
from app.app import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    public_id = db.Column(db.String, unique=True)
    admin = db.Column(db.Boolean)
    username = db.Column(db.String(50), unique=True)
    email = db.Column(db.String(50), unique=True)
    password = db.Column(db.String(100))
    subscription_plan = db.Column(db.Integer)
    created_at = db.Column(db.DateTime, index=True,
                           default=datetime.utcnow())
    updated_at = db.Column(db.DateTime, index=True, default=datetime.utcnow())

app/app.py

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash
import uuid

from app.models.user import User

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = #SQLALCHEMY_DATABASE_URI

db = SQLAlchemy(app)

# ... CRUD routes that will use User

@app.route('/user', methods=['POST'])
def create_user():
data = request.get_json()
hashed_password = generate_password_hash(data['password'])
new_user = User(
    public_id=str(uuid.uuid4()),
    username=data['username'],
    password=hashed_password,
    email=data['email'],
    admin=data['admin'],
    subscription_plan=data['subscription_plan']
)
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'User successfully created.'})


if __name__ == '__main__':
    app.run(port=5000, debug=True)

我想将 dbapp/app.py 导入到我的 app/models/user.py 文件中,但是当我尝试导入User 模型进入 app/app.py,由于循环导入,它给了我一个错误。我不知道如何解决这个问题,因为在从 app/app.py 传递 app 的实例之后,User 似乎需要 db

我还想将我的路线从这里移出并放入单独的文件中以便更好地组织,因此尝试了解避免循环导入的最佳方法。非常感谢任何和所有帮助!

【问题讨论】:

    标签: python flask flask-sqlalchemy


    【解决方案1】:

    不要让用户导入应用程序和应用程序导入用户,而是将它们放在 init 中。

    app/app.py

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    db = SQLAlchemy(app)
    

    app/models/user.py

    from app.app import db
    class User:
        pass #access db the way you want
    

    app/views.py

    from app.app import app,db
    @app.route("/")
    def home():
        return "Hello World" # use db as you want
    

    app/__init__.py

    from app import app
    from app.models.user import User
    from app import views
    

    这是解决问题的最简单方法。但是,我建议使用Application Factories

    【讨论】:

    • 太好了,谢谢!这正是我一直在寻找的。感谢您的帮助。
    • 使用 python -m app.app 运行您的示例后,我得到“ /usr/lib/python3.8/runpy.py:126: RuntimeWarning: 'app.app' found in sys.modules在导入包 'app' 之后,但在执行 'app.app' 之前;这可能会导致不可预知的行为 warn(RuntimeWarning(msg)) "
    【解决方案2】:

    我认为最好的方法是重新组织您的项目结构。尝试将视图功能移动到单独的包或模块中。您可以关注exploreflask 来组织您的项目。或者你可以查看我的 Flask 项目的common project structure

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多