本文主要是介绍pymysql 事务中的外码约束问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题
- 首先自己写了个事务内执行多个sql的包装函数,使得这些sql的操作具有原子性,中间任意一条操作出现错误都会抛出异常并回退。
# 更新数据,可以执行数据的增、删、改...def update_data(self, sqls: list):connect = self.__get_connect()cursor = connect.cursor()try:for sql in sqls:cursor.execute(sql)connect.commit()except Exception:# 出现异常则回滚,并抛出异常connect.rollback()raisefinally:cursor.close()connect.close()
- 然后在执行下边的sqls时出现了异常
"""scheme
CREATE table1 (id: INTEGER PRIMARY KEY
);
CREATE table2 (id: INTEGER PRIMARY KEY,foreign_id: INTEGER ,FOREIGN KEY(foreign_id) REFERENCES table1(id)
);
"""
sqls = ['INSERT INTO table1(id) VALUES(1);','INSERT INTO table2(id, foreign_id) VALUES(1, 1);'
]
update_data(sqls)# >>> 异常(1452, 'Cannot add or update a child row: a foreign key constraint fails ...')
- 违反外码约束?也就是说,在事务内,
execute(sql)
后缓存区的新插入数据若未commit
是不能被下一条sql获取的么…
解决方法
经过一番瞎试,找到了以下的应对方法,在execute(sql)
后fetch
一下
# 更新数据,可以执行数据的增、删、改...def update_data(self, sqls: list):connect = self.__get_connect()cursor = connect.cursor()try:for sql in sqls:cursor.execute(sql)cursor.fetchone() # 解决方法connect.commit()except Exception:# 出现异常则回滚,并抛出异常connect.rollback()raisefinally:cursor.close()connect.close()
- 看了官网文档以及网上的一些
fetch
方法的介绍,由于我python跟mysql也不是很熟悉,还是没找到fetch
能解决这个问题的原因 - 我自己考虑的是,pymysql事务的缓存机制中,缓存区也有两个部分,一个部分是准备就绪的数据,这些数据经过了处理,比较符合mysql数据库规范,即将commit到数据库中,此时能被事务中的其他操作获取;另一部分的数据还未准备就绪,仍未进行规范化处理,不能被事务中的其他操作获取。分区的目的也显而易见,准备就绪的数据在进行规范化时是比较耗时的。
execute
后的数据默认分配到就绪区,而fetch
函数则能触发数据规范化操作。 - 大家有什么看法也欢迎指正哈!灰常感谢!
这篇关于pymysql 事务中的外码约束问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!