0

0

sqlalchemy 如何写“软删除”并在查询中自动过滤已删记录

冰川箭仙

冰川箭仙

发布时间:2026-01-24 19:14:02

|

301人浏览过

|

来源于php中文网

原创

软删除是逻辑标记而非物理移除,仅用 is_deleted 字段不够,需全局拦截查询、关联加载及事件监听以确保所有数据入口均尊重该标记。

sqlalchemy 如何写“软删除”并在查询中自动过滤已删记录

什么是软删除,为什么不能只靠 is_deleted 字段

软删除本质是逻辑标记而非物理移除,但光加个 is_deleted 布尔字段远远不够。SQLAlchemy 不会自动识别这个字段的语义,所有查询(包括 session.query(Model)Model.query.all()、关联加载)默认都会拉出已标记删除的记录。必须显式干预查询构建过程,否则“软”就变成了“假装删了”。

常见错误现象:model.delete() 后查出来还在;外键关联对象仍能加载已软删的父记录;admin 后台列表里出现“已删除”的脏数据。

用 query_class + 自定义 Query 实现全局过滤

最直接可控的方式是重写模型的默认查询类,让每次 Model.querysession.query(Model) 都自动加上 is_deleted == False 条件。

实操建议:

  • 定义一个继承 Query 的子类,在 __iter__all() 调用前统一 apply filter
  • 在模型中通过 query_class 属性指定该类
  • 确保 is_deleted 字段类型为 Boolean,且有默认值 False
class SoftDeleteQuery(Query):
    def __iter__(self):
        return super().filter(self._mapper_zero().is_deleted == False).__iter__()
<p>class User(Base):
<strong>tablename</strong> = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
is_deleted = Column(Boolean, default=False)
query_class = SoftDeleteQuery

注意:这种方式对 session.query(User) 无效(它不走 User.query),需配合 session.query(User).with_polymorphic('*') 或改用 User.query 风格。

用 SQLAlchemy 2.0+ 的 select() + with_only_columns 替代旧式 query

SQLAlchemy 2.0 推荐使用 select() 构建查询,此时无法复用 query_class。需手动封装一个带过滤的查询构造器,或借助 Event 拦截 select()

VIVA
VIVA

一个免费的AI创意视觉设计平台

下载

更稳妥的做法是定义一个类方法:

class User(Base):
    # ... 字段定义同上
    @classmethod
    def not_deleted(cls):
        return select(cls).where(cls.is_deleted == False)
<h1>使用:</h1><p>stmt = User.not_deleted().where(User.name.contains('john'))
result = session.execute(stmt).scalars().all()

这样既清晰又可控,避免隐式行为。如果项目已大量使用 select(),硬塞 query_class 反而增加理解成本。

外键关联和 joinedload 时如何保持软删除语义

软删除最大的坑不在主表,而在关联——比如查订单时,joinedload(Order.user) 会把已软删的用户也一起加载进来,破坏业务一致性。

解决方案分两层:

  • 对一对一/多对一外键,在关系定义中加 primaryjoin 条件,例如:user = relationship('User', primaryjoin='and_(Order.user_id == User.id, User.is_deleted == False)')
  • 对一对多(如 User.orders),在 relationship 中加 viewonly=True + 单独定义一个 not_deleted_orders 属性,用 select() + where 显式过滤
  • 避免在 lazy='joined' 场景下依赖默认关联,容易漏掉 is_deleted 判断

真正难处理的是嵌套三层以上的关联(比如 Order → Item → Supplier),这时候推荐用 CTE 或物化视图预过滤,而不是靠 ORM 动态拼条件——性能和可读性都会迅速恶化。

软删除不是加个字段就完事,关键在于所有数据入口(CRUD、关联、批量操作、raw SQL)是否都尊重这个标记。最容易被忽略的是事件监听器(如 @event.listens_for(User, 'before_insert'))和 Alembic 迁移脚本里的初始数据插入——它们常常绕过模型层逻辑,直接写入 is_deleted = True 却没配好默认值或索引。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1133

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

381

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2152

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

380

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1683

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

585

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

440

2024.04.29

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 80.7万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号