SQLAlchemy删除匹配记录时delete()报错、all()正常如何解决
问题根因
你使用func.date()生成的是SQL函数表达式对象,SQLAlchemy ORM层的批量删除操作默认会校验同步内存中的实例状态,无法识别这类动态SQL表达式作为过滤条件,因此会触发执行错误。而query.all()属于只读查询,不需要处理实例状态变更,因此可以正常返回结果。
可行解决方案
- 方案1:关闭批量删除的同步校验
给delete()方法传入synchronize_session=False参数,跳过ORM层的实例状态同步步骤,直接执行原生批量删除SQL:from sqlalchemy import func d = func.date('2021-6-23') session.query(XCom).filter(XCom.execution_date <= d).delete(synchronize_session=False) session.commit() - 方案2:替换为Python原生日期对象
不使用SQL函数生成日期,直接传入Python原生date对象作为过滤值,ORM层可正常识别处理:from datetime import date d = date(2021, 6, 23) session.query(XCom).filter(XCom.execution_date <= d).delete() session.commit() - 方案3:先查询再逐个删除
适合符合条件的记录量较小的场景,先查询出所有匹配实例后逐个调用删除方法:from sqlalchemy import func d = func.date('2021-6-23') objs = session.query(XCom).filter(XCom.execution_date <= d).all() for obj in objs: session.delete(obj) session.commit()
注意:所有删除操作执行后都需要调用
session.commit()才能将变更持久化到数据库。
内容的提问来源于stack exchange,提问作者biak
相关产品推荐
相关产品推荐

