Flask-Sqlalchemy 事务

数据库事务

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。例如,在新增数据A后更新数据B,当更新数据B失败后,要回滚数据库,使得数据A不能新增到数据库中,这就是数据的原子性。

  • 原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。
  • 一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序 串行执行的结果相一致。
  • 夺隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
  • 夺持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。

Flask-Sqlalchemy中的事务

在flask中,如果要想保证事务的原子性应该如何操作呢?
看下面这个例子:

业务逻辑
新增分组并保存分组与用户的关联关系。在分组表中新增一个分组并获取到分组id,然后在关联表中循环插入分组与用户的关联关系。
数据库表结构
数据库中有一个分组表(case_group)和分组权限表(user_auth),分组权限表中保存组id和用户id来关联用户和分组,用户和分组是多对多的关系。此处省略用户表。

CREATE TABLE `case_group` (
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `delete_time` datetime DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '分组id',
  `name` varchar(20) DEFAULT NULL COMMENT '分组名称 全局唯一不可重复',
  `info` varchar(50) DEFAULT NULL COMMENT '分组描述',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;

CREATE TABLE `user_auth` (
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `delete_time` datetime DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '用户id',
  `auth_id` int(11) NOT NULL COMMENT '权限id',
  `type` smallint(6) NOT NULL COMMENT '权限id类型 ;  1 -> group分组 |  2 -> project工程',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4;

模型中操作数据库的方法

    @classmethod
    def new_group(cls, form):
        group = CaseGroup.query.filter_by(name=form.name.data, delete_time=None).first()
        if group is not None:
            raise ParameterException(msg='分组已存在')
        # 新增分组的时候同时新增可查看当前用例组的人员。当出现问题时进行回滚,人员和分组都不插入
        try:
            group = CaseGroup()
            group.name = form.name.data
            group.info = form.info.data
            db.session.add(group)
            db.session.flush()
            if form.users.data:
                current_app.logger.info(group.id)
                for user in form.users.data:
                    user_auth = UserAuth()
                    user_auth.user_id = user
                    user_auth.auth_id = group.id
                    user_auth.type = UserAuthEnum.GROUP
                    db.session.add(user_auth)
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            raise UnknownException(msg='新增异常 数据已回滚')

        return True

用try except 将2次新增操作包裹起来,当出现异常时使用db.session.rollback()进行数据回滚。
在一次新增后使用db.session.add()进行数据暂存,此时并未真正提交到数据库中,需要在所有操作执行后执行db.session.commit()进行数据提交。
在这个例子中,新增关联表的数据需要已新增分组数据的id,此时未commit所以自增id为None,需要在新增分组后使用db.session.flush()刷新获取分组id。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`Flask-SQLAlchemy` 是 Flask 中用于操作数据库的扩展,它提供了丰富的可配置项。以下是一些常用的可配置项: - `SQLALCHEMY_DATABASE_URI`:数据库连接 URI,格式为 `dialect+driver://username:password@host:port/database`。 - `SQLALCHEMY_TRACK_MODIFICATIONS`:是否追踪数据库模型的修改,如果为 True,会占用额外的内存,并且会在每次请求结束后自动提交修改,如果为 False,需要手动提交修改。 - `SQLALCHEMY_POOL_SIZE`:连接池大小,即连接池中最多可以同时存在的连接数。 - `SQLALCHEMY_POOL_TIMEOUT`:获取连接的超时时间,即连接池中没有可用连接时等待的最长时间。 - `SQLALCHEMY_POOL_RECYCLE`:连接池中连接的回收时间,即连接在连接池中的最长生命周期,超过这个时间会被回收并重新创建连接。 - `SQLALCHEMY_ENGINE_OPTIONS`:数据库引擎配置,常见的配置项包括 `isolation_level`(事务隔离级别)、`echo`(是否输出 SQL 语句)等。 例如,如果要将数据库连接 URI 设置为 PostgreSQL 数据库,并且将连接池大小设置为 10,可以使用以下代码: ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@localhost/mydatabase' app.config['SQLALCHEMY_POOL_SIZE'] = 10 db = SQLAlchemy(app) ``` 当然,还有很多其他的可配置项,具体可以参考 Flask-SQLAlchemy 的文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值