• flask-sqlalchemy结合Blueprint遇到循环引入问题的解决方案


    想要用flask_sqlalchemy结合Blueprint分模块写一下SQL的增删改查接口,结果发现有循环引入问题。

    一开始,我在app.py中使用db = SQLAlchemy(app)创建数据库对象;并且使用app.register_blueprint(db_bp, url_prefix='/db')注册蓝图。

    这使得我的依赖关系是这样的。db.py → app,py 中的db对象;app.py → db,py 用于注册蓝图,产生了循环引用。

    接着我学着使用一个model.py来存放db变量,但是使用错误,下面是错误的示例。

    我在model.py使用db = SQLAlchemy()创建了未注册的db对象

    在app.py中使用db.init_app(app)来连接数据库,注册db对象

    但在db.py中错误引用了app.py中的db对象,再次产生了循环引用

    解决方法,在db.py中引入model.py中的db对象即可。

    此时的依赖关系如下,db.py和app.py → model.py 用于获取db对象;app.py → db.py 用于注册蓝图。

     

    看到一些比较麻烦的解决方案,1. 把db变量变成一个web接口,用请求的方式获取。

    2. 把app注册db和blueprint的操作都放入main函数中。或者,先封装到def create_app()函数中,然后在main函数中调用。

    参考 使用Flask-SQLAlchemy和Blueprints循环导入db引用 | 那些遇到过的问题

     

    dao.py

    1. from flask import Blueprint, request, jsonify
    2. from models import db
    3. from models import KnowledgeEntity
    4. from sqlalchemy.exc import SQLAlchemyError
    5. # 创建视图函数蓝图
    6. app = Blueprint('KnowledgeDAO', __name__)
    7. '''
    8. word = db.Column(db.String(255), primary_key=True)
    9. content = db.Column(db.Text, unique=True, nullable=False)
    10. priority = db.Column(db.String(255), unique=True, nullable=False)
    11. association = db.Column(db.JSON, unique=True, nullable=False)
    12. '''
    13. # 创建用户
    14. @app.route('/add', methods=['POST'])
    15. def create_user():
    16. data = request.get_json()
    17. word = data.get('word')
    18. content = data.get('content')
    19. priority = data.get('priority')
    20. association = data.get('association')
    21. if not word or not priority:
    22. return jsonify({'message': 'Both word and priority are required'}), 400
    23. entity = KnowledgeEntity(word=word, content=content, priority=priority, association=association)
    24. try:
    25. db.session.add(entity)
    26. db.session.commit()
    27. return jsonify(1), 201
    28. except SQLAlchemyError as e:
    29. db.session.rollback() # 回滚事务以撤销之前的操作
    30. error_message = str(e)
    31. return f'Error: {error_message}', 500
    32. # 查询所有用户
    33. @app.route('/selectAll', methods=['POST'])
    34. def get_users():
    35. users = KnowledgeEntity.query.all()
    36. print('users',users)
    37. # user_list = [{'id': user.id, 'username': user.username, 'email': user.email} for user in users]
    38. return jsonify(1)

     model.py

    1. from flask_sqlalchemy import SQLAlchemy
    2. db = SQLAlchemy()
    3. class KnowledgeEntity(db.Model):
    4. __tablename__ = 'knowledge'
    5. word = db.Column(db.String(255), primary_key=True)
    6. content = db.Column(db.Text, unique=True, nullable=False)
    7. priority = db.Column(db.String(255), unique=True, nullable=False)
    8. association = db.Column(db.JSON, unique=True, nullable=False)
    9. def __init__(self, word, content=None, priority=None, association=None):
    10. self.word = word
    11. self.content = content
    12. self.priority = priority
    13. self.association = association

     app.py(改进后的)

    1. from flask import Flask, request, jsonify,g
    2. from flask_cors import CORS
    3. from flask_sqlalchemy import SQLAlchemy
    4. from models import db
    5. # 导入视图函数
    6. from DAO import KnowledgeDAO
    7. app = Flask(__name__)
    8. # 配置选项,用于控制 Flask 在将 Python 字典转换为 JSON 数据时是否按照键的字母顺序对键进行排序,默认情况下,它的值为 True,表示会对键进行排序。
    9. app.config['JSON_SORT_KEYS'] = False
    10. app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/ennote'
    11. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    12. # 注册跨域
    13. CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问所有api
    14. # 连接数据库
    15. db.init_app(app)
    16. # 注册蓝图
    17. app.register_blueprint(KnowledgeDAO.app, url_prefix='/knowledge')
    18. if __name__ == '__main__':
    19. # 创建应用上下文
    20. with app.app_context():
    21. # 在这里执行需要应用上下文的操作
    22. # 例如,访问数据库或使用Flask的全局变量
    23. db.create_all()
    24. app.run(host='127.0.0.1', port=5000, debug=True)

  • 相关阅读:
    Python之numpy数组篇(上)
    async和await、以及他们和promise的区别?
    2019 校招多益网络软件开发java 笔试题
    openssl/rc4.h: 没有那个文件或目录
    视图、存储过程、触发器
    MongoDB——将时间戳转换为日期
    无代码开发添加数据入门教程
    C++ Reference: Standard C++ Library reference: C Library: cctype
    【名城优企游学】国轩高科,用数字化带来强劲发展动力
    2022.9.5-9.11 AI行业周刊(第114期):分享的快乐
  • 原文地址:https://blog.csdn.net/qq_60293814/article/details/133531002