Beego ORM 默认自动过滤软删除记录,即在Read、QueryTable等查询中隐式添加is_deleted=0或deleted_at IS NULL条件;需用Raw原生SQL或确保字段未标记softdelete并配合Filter才能查出已软删数据。

Beego ORM 默认会过滤掉软删除标记的记录
Beego ORM 的 SoftDelete 字段(如 IsDeleted 或 DeletedAt)一旦被识别,Read、QueryTable、Filter 等常规查询方法默认**自动添加 WHERE is_deleted = 0 或 WHERE deleted_at IS NULL 条件**,不会返回已软删除的数据。这不是 bug,而是设计行为。
想查出软删除的数据,必须显式绕过软删除过滤
Beego ORM 提供了两个明确的机制来取消软删除拦截:
-
orm.NewOrm().NoCache().Raw("SELECT * FROM user_info WHERE is_deleted = 1").All(&users)—— 直接用Raw执行原生 SQL,完全跳过 ORM 的软删逻辑 -
o := orm.NewOrm(); o.QueryTable(&Userinfo{}).Filter("is_deleted", 1).All(&users)—— 使用Filter显式指定软删字段值,但前提是模型中该字段**没被标记为orm.SoftDelete**;如果已被标记,需先在结构体标签里移除或重命名该字段 - 更稳妥的做法:定义一个“非软删视图”结构体,字段名与表一致但不带
orm.SoftDelete标签,再用QueryTable查询
软删除字段必须正确声明才能被 ORM 识别
Beego ORM 只有在模型字段上显式使用 orm.SoftDelete 标签时,才会启用自动过滤。常见错误写法:
- 字段名写成
IsDeleted但没加orm:"column(is_deleted);type(tinyint);default(0);softdelete"—— ORM 不识别,也就不会过滤,但你也得不到软删语义保障 - 用了
DeletedAt *time.Time却没配orm:"auto_now_add;type(datetime);null"+softdelete—— 时间类型软删需额外注意空值和索引兼容性 - 字段名是
deleted,但标签写成orm:"column(deleted);default(0)"缺少softdelete—— 同样不触发过滤
正确示例:IsDeleted bool `orm:"column(is_deleted);default(0);softdelete"`
QueryTable 查询时 softdelete 字段不能用作 Filter 主键条件
如果你执行 o.QueryTable(&Userinfo{}).Filter("id", 123).One(&u),即使该记录 is_deleted = 1,也不会返回——因为 One 内部仍走软删过滤路径。此时必须:
- 改用
Raw+QueryRow获取单条 - 或先用无过滤的
Filter("is_deleted", 1).Filter("id", 123)查找,再手动检查结果长度 - 注意:Beego ORM 没有类似 GORM 的
Unscoped()全局开关,每个查询都得单独处理
最容易被忽略的是:软删除逻辑只作用于 QueryTable 和 Read 系列方法,对 Raw 和 Prepare 完全透明——这点既是限制,也是你绕过的唯一可靠出口。











