zoukankan      html  css  js  c++  java
  • flask插件系列之SQLAlchemy实用技巧

    下面记录一下SQLAlchemy使用的技巧。

    在多模块下定义models

    • 如果由多个蓝图下读定义了model模块,在初始化的时候需要加载到上下文中。

    当使用flask_Migrate迁移数据库的时候,当执行:

    python manage.py db migrate -m '修改说明'
    

    db会默认去上下文中寻找定义的models模型,所以必须在初始化app的时候加载相关models的上下文;因此所有相关的model.py文件都应该在初始化app的时候:

    from XXX import model
    

    数据迁移的坑

    1. SQLAlchemy当model发生了修改的时候,其是不能识别字段的的类型和字段大小的。
    from extensions import db
    
    class User(db.model)
        __tablename__ = 'users'
        user_id = db.Column(db.String(8), primary_key=True) 
    
    # 改为
    class User(db.model)
        __tablename__ = 'users'
        user_id = db.Column(db.String(20), primary_key=True) 
    

    问题:直接迁移会出现no change,因为不会检测字段的类型。

    办法:修改字段的名字迁移后再将字段改回迁移,相当于删除原来的字段重新创建;

    1. 当当前的versions和数据库的版本不一致导致无法迁移时。

    办法:

    # 删除原来的migrations文件夹;
    # 去数据库删除alembic_version表的内容;
    # 重新执行数据库迁移操作;
    

    手动初始化SQLAlchemy

    在有些时候,我们没有初始化APP,但是又想使用models中定义的模型和数据库的ORM操作,那么就需要手动初始化了。

    from sqlalchemy import create_engine
    from sqlalchemy.orm import scoped_session, sessionmaker
    from models import AdminUser
    
    # 创建一个配置对象
    engine = create_engine('mysql+pymysql://username:passwd@ip:port/db?charset=utf8', convert_unicode=True)
    # 创建一个会话
    db_session = scoped_session(sessionmaker(autocommit=False,
                                             autoflush=False,
                                             bind=engine))
    # 初始化查询对象
    AdminUser.query = db_session.query_property()
    
    # 下面就跟在框架中一样了
    admin = AdminUser()
    admin.id = 1
    admin.username = username
    admin.password = pwd
    db_session.add(admin)
    db_session.commit()                                         
    

    查询报错:sqlalchemy.exc.InvalidRequestError: Can't reconnect until invalid transaction is rolled back

    • 原因是:连接断开后,事务没有回滚,残留的锁导致后续的查询报错.sqlalchemy对每一个查询和插入等操作都是一个事务。

    • 解决:在所有的数据库操作的时候捕捉异常进行事务的回滚。

    # main.py
    from models import OrderInfo 
    from sqlalchemy.exc import InvalidRequestError
    try:
        order = OrderInfo.query.filter_by(task_id=user_dict.get('task_id')).first()
        order.status = 'COMPLETE'
        db.session.commit()
    except InvalidRequestError:
        db.session.rollback()
    except Exception as e:
        print(e)
    
  • 相关阅读:
    Spring事务
    org.apache.catalina.webresources.Cache.getResource Unable to add the resource
    CentOS7下zip解压和unzip压缩文件
    通过Maven插件发布JaveEE项目到tomcat下
    MYSQL5.7版本sql_mode=only_full_group_by问题
    CentOS下安装Tomcat
    MYSQL57密码策略修改
    CentOS下安装mysql5.7和mysql8.x
    Linux下使用systemctl命令
    076-PHP数组修改元素值
  • 原文地址:https://www.cnblogs.com/cwp-bg/p/9263609.html
Copyright © 2011-2022 走看看