Flask-SQLAlchemy报current transaction is aborted错误排查
问题根因
你看到的psycopg2.errors.InFailedSqlTransaction报错和你写的这条分组查询没有关系——你把SQLAlchemy生成的语句直接放到PSQL里能正常返回结果,已经证明这条查询本身语法、逻辑都是对的。
这个报错是PostgreSQL的事务保护机制触发的:在你执行这条查询之前,当前数据库会话里已经有一条SQL语句执行失败了,PostgreSQL会直接把整个事务标记为异常中止状态,在事务回滚之前,所有后续发过来的SQL都会被直接拒绝,根本不会被执行,所以才会抛这个错。
常见的触发场景:
- 之前执行过其他增删改查操作,出现了字段不存在、约束冲突、语法错误之类的问题,没有做回滚处理就直接执行新查询
- 在Python交互式shell里调试代码时,之前跑错了语句,没清理会话状态就接着写新逻辑
- 项目里没有配置异常场景下的自动回滚逻辑,失败的SQL把事务卡成了坏状态
另外你写的SQLAlchemy代码还漏了原生SQL里的排序逻辑,和报错无关,但会导致返回结果顺序和原生SQL不一致。
修复步骤
- 先清理异常事务状态
在执行你的查询代码之前,先调用会话的回滚方法,把中止的事务关掉:# Flask-SQLAlchemy用db.session,原生SQLAlchemy替换为你自己创建的会话对象即可 db.session.rollback() - 补全查询的排序逻辑,和原生SQL对齐
修正后的完整查询代码:result = Venue.query.with_entities( func.count(Shows.id), Venue.name, Venue.city, Venue.state ).join(Shows).group_by( Venue.name, Venue.city, Venue.state ).order_by(func.count(Shows.id)).all() - 定位前置错误(可选)
如果回滚后这个问题反复出现,把SQLAlchemy的SQL日志打开,找到当前事务里第一条执行失败的语句,修掉对应的代码逻辑即可。开日志的配置:engine = create_engine("你的数据库连接地址", echo=True)
日常调试的时候,每次执行代码报错后先手动跑一次回滚清状态,再执行新代码,就不会反复碰到这个拦截错误。
内容的提问来源于stack exchange,提问作者Reinmarius
相关产品推荐
相关产品推荐

