SQLAlchemy 一次 commit 多条数据,某条数据出错时调用 db.session.rollback 只回滚了出错的那一条记录?

麻烦哪个大哥能帮忙看下,flask用sqlalchemy插入多条数据:

try:
   
    role1=Role(name="11")
    role2=Role(name="22")
    role3=Role(name="22")
    db.session.add(role1)
    db.session.add(role2)
    db.session.add(role3)
    db.session.commit()
except: 
    db.session.rollback()
    print("有错误")
else:
    
    print("成功")

问题是:Role数据表的name字段是不可重复的,我预期是出错了三条记录都不能写入数据库,可实际是前面两条写入了,rollback不是可以回滚事务吗,为什么不能回滚呢。

问题你三条add也是各自执行,没有在一个事务里面啊

试试

with db.session.begin():
    db.session.add(role1)
    db.session.add(role2)
    db.session.add(role3)
db.session.commit()
2 个赞

改成你这样他会提示 raise sa_exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: A transaction is already begun. Use subtransactions=True to allow subtransactions.
然后我改成:
with db.session.begin(subtransactions=True):
db.session.add(role1)
db.session.add(role2)
db.session.add(role3)
db.session.commit()
结果还是 一样,不出错的还是会被写入到数据库,是不是mysql哪里需要设置,或者sqlalchemy哪里需要设置变量呢

没人能回答吗

麻烦重新创建数据库再试一下,我在本地没法重现你的问题:

>>> Role.query.all()
[]
>>> role1=Role(name="11")
>>> role2=Role(name="22")
>>> role3=Role(name="22")
>>> db.session.add(role1)
>>> db.session.add(role2)
>>> db.session.add(role3)
>>> try:
...     db.session.commit()
... except:
...     db.session.rollback()
...     print("有错误")
... else:
...     print("成功")
...
有错误
>>> Role.query.all()
[]

建议你贴出你的sqlalchemy的版本
如果是1.4版本以后的新版本sqlalchemy一楼的听该是对的,你课可以尝试一下
try:
db.session.begin(subtransactions=True)
role1=Role(name=“11”)
db.session.add(role1)

db.session.commit()
except Exception:
db.session.rollback()

请问python版本和sqlalchemy的版本是多少啊

sqlalchemy.exc.InvalidRequestError: A transaction is already begun. Use subtransactions=True to allow subtransactions.
这个问题也可能是在你with db.session.begin()之前还有过操作数据库的步骤,也就是之前的session还没有close掉,你应该可以把之前的session给close或或者commit一下再试试看