PyMySQL - 回滚测试

本文探讨了Python中如何使用多个cursor在Connection上执行SQL操作,包括并发执行、异常处理与回滚,以及不同情况下的数据行为。重点展示了单个rollback对所有cursor的影响和跨函数的回滚规则。

cursor唯一?

结论:一个Connection可以创建多个cursor

def test():
    conn = connect()
    cursor = conn.cursor()
    print(cursor == conn.cursor())  # False

rollback demo1: 已提交数据

结果:插入成功
结论:已经提交的无法回滚

def test():
    conn = connect()
    cursor = conn.cursor()
    try:
        cursor.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['a1', 'a2'])
        conn.commit()  # 提交
        print(1 / 0)
    except Exception as e:
        print(e)  # division by zero
        conn.rollback()
    finally:
        cursor.close()
        conn.close()

rollback demo2: 代码异常 & 单cursor

  1. 插入两条数据,无异常
    def test():
        conn = connect()
        cursor = conn.cursor()
        try:
            cursor.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['a1', 'a2'])
            cursor.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['b1', 'b2'])
        except Exception as e:
            print(e)
            conn.rollback()
        finally:
            conn.commit()
            cursor.close()
            conn.close()
    
    查看数据库:在这里插入图片描述
  2. 再插入两条数据,发生异常,触发了回滚
    def test():
        conn = connect()
        cursor = conn.cursor()
        try:
            cursor.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['a1', 'a2'])
            print(1 / 0)
            cursor.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['b1', 'b2'])
        except Exception as e:
            print(e)  # division by zero
            conn.rollback()
        finally:
            conn.commit()
            cursor.close()
            conn.close()
    
    查看数据库:在这里插入图片描述
  3. 再无异常插入两条,此时id已经从4开始了
    在这里插入图片描述

rollback demo3: SQL异常 & 多cursor

结果:触发回滚,未插入一条数据
结论:rollback()是对当前Connection中的所有的cursor进行回滚操作

def test():
    conn = connect()
    cursor1 = conn.cursor()
    cursor2 = conn.cursor()
    try:
        cursor1.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c1-01', 'c1-02'])
        cursor2.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c2-01', 'c2-02'])
        cursor1.execute('insert into1 `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c1-11', 'c1-12'])
    except Exception as e:
        print(e)  # (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '`pymysql_rollback_test`(field1, field2) values ('c1-11', 'c1-12')' at line 1")
        conn.rollback()
    finally:
        conn.commit()
        cursor1.close()
        cursor2.close()
        conn.close()

去除异常的SQL语句,再次插入两条数据:

def test():
    conn = connect()
    cursor1 = conn.cursor()
    cursor2 = conn.cursor()
    try:
        cursor1.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c1-01', 'c1-02'])
        cursor2.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c2-01', 'c2-02'])
        # cursor1.execute('insert into1 `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c1-11', 'c1-12'])
    except Exception as e:
        print(e)
        conn.rollback()
    finally:
        conn.commit()
        cursor1.close()
        cursor2.close()
        conn.close()

查看数据库,id3开始:
在这里插入图片描述

rollback demo3: 跨函数

结果:无论是err1()还是err2(),都会触发回滚,最终未插入一条数据
结论:与所处函数无关

def test():
    conn = connect()
    cursor1 = conn.cursor()
    cursor2 = conn.cursor()
    try:
        cursor1.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c1-01', 'c1-02'])
        cursor2.execute('insert into `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c2-01', 'c2-02'])
        err1()
        # err2(cursor2)
    except Exception as e:
        print(e)  # No active exception to reraise
        conn.rollback()
    finally:
        conn.commit()
        cursor1.close()
        cursor2.close()
        conn.close()


def err1():
    raise


def err2(cursor):
    cursor.execute('insert into1 `pymysql_rollback_test`(field1, field2) values (%s, %s)', ['c2-21', 'c2-22'])
### Python自动化测试中的数据回滚实现 在Python中,可以通过`pymysql`库连接MySQL数据库并执行SQL语句来完成数据的增删改查以及事务管理。为了实现测试数据的回滚,通常会利用数据库事务的功能,在操作前开启事务,并在必要时调用回滚命令撤销未提交的操作[^1]。 下面展示了一个完整的示例代码,用于演示如何通过Python脚本控制MySQL数据库并实现测试数据的回滚: ```python import pymysql def rollback_test_data(): try: # 连接数据库 connection = pymysql.connect( host='localhost', user='root', password='password', database='test_db' ) with connection.cursor() as cursor: # 开启事务 connection.begin() # 插入一条测试数据 sql_insert = "INSERT INTO users (name, age) VALUES (%s, %s)" cursor.execute(sql_insert, ('John Doe', 30)) # 查询刚刚插入的数据 sql_select = "SELECT * FROM users WHERE name=%s" cursor.execute(sql_select, ('John Doe')) result = cursor.fetchone() print(f"Inserted Data: {result}") # 故意制造错误以触发回滚 raise Exception("Simulated error to trigger rollback") # 提交事务(如果一切正常) connection.commit() except Exception as e: print(f"Error occurred: {e}") # 发生异常时回滚事务 connection.rollback() print("Transaction rolled back successfully.") finally: # 关闭数据库连接 connection.close() if __name__ == "__main__": rollback_test_data() ``` 上述代码展示了如何在一个函数中处理数据库事务。当发生异常时,程序会自动调用`connection.rollback()`来回滚所有尚未提交的变化,从而确保测试环境的一致性。 #### 注意事项 - **事务管理**:在实际应用中,建议始终使用显式的事务管理机制,而不是依赖于默认的行为。 - **异常捕获**:通过捕捉可能发生的各种异常情况,可以更精确地决定何时需要进行回滚操作。 - **资源释放**:无论是否成功还是失败,都需要确保关闭数据库连接以避免潜在的内存泄漏问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值