You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SqlModel删除符合指定条件的所有行?

SqlModel批量删除符合条件记录的优化方案

问题背景

SqlModel官方文档中展示了用.one()或.first()获取单条记录后执行删除的方法,示例代码如下:

def delete_heroes():
    with Session(engine) as session:
        statement = select(Hero).where(Hero.name == "Spider-Youngster")
        results = session.exec(statement)
        hero = results.one()
        print("Hero: ", hero)

        session.delete(hero)
        session.commit()

但当需要删除所有符合条件的记录时,直接用.all()获取列表后调用session.delete()会报错:sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.list' is not mapped,错误代码如下:

def delete_heroes():
    with Session(engine) as session:
        statement = select(Hero).where(Hero.name == "Spider-Youngster")
        results = session.exec(statement)
        hero = results.all()
        print("Hero: ", hero)

        session.delete(hero)
        session.commit()

目前通过循环遍历结果逐一删除可以实现需求,但希望找到无需循环的实现方式。

无需循环的解决方案

方法1:直接执行批量删除语句(推荐)

直接构造DELETE语句在数据库层面执行,无需将对象加载到内存,效率更高,也不需要循环:

from sqlmodel import delete

def delete_heroes():
    with Session(engine) as session:
        # 构造批量删除语句
        statement = delete(Hero).where(Hero.name == "Spider-Youngster")
        # 执行删除
        result = session.exec(statement)
        # 提交事务
        session.commit()
        # 获取删除的记录数
        print(f"成功删除 {result.rowcount} 条记录")

方法2:批量删除已加载的对象

如果业务需要先加载对象(比如要读取对象属性、触发ORM事件),可以使用session.bulk_delete_objects()方法,直接传入对象列表完成批量删除:

def delete_heroes():
    with Session(engine) as session:
        statement = select(Hero).where(Hero.name == "Spider-Youngster")
        # 加载所有符合条件的对象
        heroes = session.exec(statement).all()
        print("待删除的英雄: ", heroes)
        # 批量删除对象列表
        session.bulk_delete_objects(heroes)
        session.commit()

注意:bulk_delete_objects()不会触发ORM的before_delete/after_delete等事件,适合纯批量删除场景。

补充:修正原循环代码的问题

原循环代码存在一个隐性错误:调用results.all()后,结果集已经被完全消费,后续for result in results不会遍历到任何数据。正确的写法应该遍历存储结果的变量:

def delete_heroes():
    with Session(engine) as session:
        statement = select(Hero).where(Hero.name == "Spider-Youngster")
        heroes = session.exec(statement).all()
        print("Hero: ", heroes)

        for hero in heroes:
            session.delete(hero)

        session.commit()

内容的提问来源于stack exchange,提问作者RaamEE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:54:57