当前位置:首页 > Python > 正文

Python标记删除实现教程 - 详解软删除技术 | Python数据管理指南

Python标记删除实现教程 - 详解软删除技术

本教程将详细介绍Python中实现标记删除(软删除)的技术方法,包含核心概念、实现步骤和完整代码示例。

什么是标记删除?

标记删除(软删除)是一种数据管理技术,它不会真正从数据库中删除记录,而是通过设置一个特殊标记字段(如is_deleted)来标记记录为"已删除"状态。这种技术相比物理删除具有多项优势:

  • 数据恢复简单 - 只需修改标记状态
  • 保留历史记录 - 满足审计需求
  • 避免级联删除问题
  • 提高数据安全性

标记删除 vs 物理删除

对比项 标记删除 物理删除
数据恢复 容易 困难
性能影响 高(特别是大表)
数据完整性 保留历史数据 永久丢失

Python实现标记删除的步骤

1. 数据库设计

在数据库表中添加标记字段:

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL,
    is_deleted BOOLEAN DEFAULT FALSE,  -- 标记删除字段
    deleted_at TIMESTAMP NULL     -- 可选:记录删除时间
);

2. Python实现标记删除

import sqlite3
from datetime import datetime

class UserManager:
    def __init__(self, db_path):
        self.conn = sqlite3.connect(db_path)
        self.cursor = self.conn.cursor()
        self._create_table()
    
    def _create_table(self):
        """创建用户表"""
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                email TEXT NOT NULL,
                is_deleted BOOLEAN DEFAULT 0,
                deleted_at TIMESTAMP
            )
        ''')
        self.conn.commit()
    
    def add_user(self, name, email):
        """添加新用户"""
        self.cursor.execute('''
            INSERT INTO users (name, email) VALUES (?, ?)
        ''', (name, email))
        self.conn.commit()
        return self.cursor.lastrowid
    
    def mark_delete(self, user_id):
        """标记删除用户"""
        self.cursor.execute('''
            UPDATE users 
            SET is_deleted = 1, deleted_at = ?
            WHERE id = ?
        ''', (datetime.now(), user_id))
        self.conn.commit()
    
    def recover_user(self, user_id):
        """恢复已删除的用户"""
        self.cursor.execute('''
            UPDATE users 
            SET is_deleted = 0, deleted_at = NULL
            WHERE id = ?
        ''', (user_id,))
        self.conn.commit()
    
    def get_active_users(self):
        """获取所有未删除的用户"""
        self.cursor.execute('''
            SELECT id, name, email FROM users WHERE is_deleted = 0
        ''')
        return self.cursor.fetchall()
    
    def get_deleted_users(self):
        """获取所有已删除的用户"""
        self.cursor.execute('''
            SELECT id, name, email, deleted_at FROM users WHERE is_deleted = 1
        ''')
        return self.cursor.fetchall()
    
    def close(self):
        """关闭数据库连接"""
        self.conn.close()

# 使用示例
if __name__ == "__main__":
    manager = UserManager("users.db")
    
    # 添加用户
    manager.add_user("张三", "zhangsan@example.com")
    manager.add_user("李四", "lisi@example.com")
    
    # 标记删除用户
    manager.mark_delete(1)
    
    # 获取活跃用户
    active_users = manager.get_active_users()
    print("活跃用户:", active_users)
    
    # 获取已删除用户
    deleted_users = manager.get_deleted_users()
    print("已删除用户:", deleted_users)
    
    # 恢复用户
    manager.recover_user(1)
    
    manager.close()

3. 查询时过滤已删除数据

在所有查询中添加过滤条件,排除已标记删除的记录:

# 获取单个用户(排除已删除)
def get_user(self, user_id):
    self.cursor.execute('''
        SELECT id, name, email 
        FROM users 
        WHERE id = ? AND is_deleted = 0
    ''', (user_id,))
    return self.cursor.fetchone()

# 统计活跃用户数量
def count_active_users(self):
    self.cursor.execute('''
        SELECT COUNT(*) 
        FROM users 
        WHERE is_deleted = 0
    ''')
    return self.cursor.fetchone()[0]

最佳实践建议

  • 使用标准化字段名 - 在整个项目中统一使用如is_deleted的字段名
  • 添加删除时间戳 - 记录删除时间有助于审计和数据分析
  • 实现自动过滤 - 在ORM或数据访问层自动添加过滤条件
  • 定期归档数据 - 对长期标记删除的数据进行归档处理
  • 权限管理 - 限制查看已删除数据的权限
  • 性能优化 - 为标记字段添加索引,特别是大型数据表

在ORM框架中的实现

在SQLAlchemy等ORM框架中,可以通过混合属性和事件监听实现自动过滤:

from sqlalchemy import Column, Integer, String, Boolean, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import event
from sqlalchemy.orm import Session, Query

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    email = Column(String(100), nullable=False)
    is_deleted = Column(Boolean, default=False)
    deleted_at = Column(DateTime)
    
    @classmethod
    def active_users(cls):
        """查询作用域:仅返回未删除的用户"""
        return Query(cls).filter_by(is_deleted=False)

# 添加事件监听器,在查询前自动添加过滤条件
@event.listens_for(Session, 'do_orm_execute')
def apply_active_filter(execute_state):
    if execute_state.is_select and not execute_state.is_column_load:
        if not execute_state.execution_options.get('include_deleted', False):
            execute_state.statement = execute_state.statement.where(
                User.is_deleted == False
            )

# 使用示例
session.query(User).all()  # 只会返回未删除的用户
session.query(User).execution_options(include_deleted=True).all()  # 返回所有用户

总结

Python标记删除(软删除)是一种强大的数据管理技术,通过本教程你已学习到:

  1. 标记删除的核心概念及优势
  2. 数据库表设计的最佳实践
  3. Python实现标记删除的完整代码示例
  4. 在ORM框架中的高级实现方法
  5. 相关性能优化和最佳实践

在实际应用中,请根据项目需求调整实现细节,平衡数据保留策略和系统性能。

发表评论