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

如何在Flask+SQLAlchemy中实现paranoid/underscored特性并构建User模型?

Flask-SQLAlchemy 实现对应Sequelize的User模型及特性

我希望为数据库创建一个User模型,如何编写类似下述Sequelize代码的SQLAlchemy User模型?如何在Flask+SQLAlchemy应用中使用Sequelize的paranoid和underscored特性?此外,如何添加created_at、updated_at这类时间戳字段?

对应的Sequelize代码:

class User extends Model {
}

User.init({
    id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
    },
    name: {
        type: DataTypes.STRING,
        allowNull: true,
    },
    email: {
        type: DataTypes.STRING,
    },
    is_verified: {
        type: DataTypes.BOOLEAN,
        defaultValue: false
    },
    email_verified_at: {
        type: DataTypes.DATE,
        allowNull: true,
    },
    password: {
        type: DataTypes.STRING,
    },
    disabled_at: {
        type: DataTypes.DATE,
        allowNull: true,
    },
    remember_token: {
        type: DataTypes.STRING,
        allowNull: true,
    },
    fcm_token: {
        type: DataTypes.STRING,
        allowNull: true,
    },
},
{
    sequelize,
    modelName: 'users',
    tableName: 'users',
    createdAt: 'created_at',
    updatedAt: 'updated_at',
    paranoid: true,
    underscored: true
});

export default User;

1. 编写对应的Flask-SQLAlchemy User模型

我们可以通过Mixin封装重复逻辑(时间戳、软删除),再定义User模型:

首先导入依赖:

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

初始化SQLAlchemy:

db = SQLAlchemy()

封装通用Mixin

先写时间戳和软删除的Mixin,复用性更强:

# 时间戳Mixin,对应created_at、updated_at
class TimestampMixin:
    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

# 软删除Mixin,对应Sequelize的paranoid特性
class SoftDeleteMixin:
    deleted_at = db.Column(db.DateTime, nullable=True)

    # 自定义软删除方法
    def soft_delete(self):
        self.deleted_at = datetime.utcnow()
        db.session.commit()

    # 重写query方法,自动过滤已软删除的记录
    @classmethod
    def query(cls):
        return super().query.filter(cls.deleted_at.is_(None))

定义User模型

class User(SoftDeleteMixin, TimestampMixin, db.Model):
    __tablename__ = 'users'  # 对应Sequelize的tableName

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String, nullable=True)
    email = db.Column(db.String, nullable=False)  # Sequelize未指定allowNull时默认false
    is_verified = db.Column(db.Boolean, default=False, nullable=False)
    email_verified_at = db.Column(db.DateTime, nullable=True)
    password = db.Column(db.String, nullable=False)
    disabled_at = db.Column(db.DateTime, nullable=True)
    remember_token = db.Column(db.String, nullable=True)
    fcm_token = db.Column(db.String, nullable=True)

2. 实现Sequelize的核心特性

underscored特性

Sequelize的underscored: true是将模型驼峰命名的属性自动转为下划线格式的数据库列名。在上面的代码中,我们直接用下划线命名模型属性(比如email_verified_at),列名和属性名一致,完全符合要求。

如果想用驼峰命名模型属性(比如emailVerifiedAt),只需要在定义字段时指定name参数:

emailVerifiedAt = db.Column(db.DateTime, name='email_verified_at', nullable=True)

另外,若要让SQLAlchemy自动生成的外键、约束名也遵循下划线格式,可以在Flask配置中添加命名约定:

app.config['SQLALCHEMY_NAMING_CONVENTION'] = {
    "ix": 'ix_%(column_0_label)s',
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(constraint_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}

paranoid特性

Sequelize的paranoid: true实现软删除(标记deleted_at而非物理删除),我们通过SoftDeleteMixin实现了相同逻辑:

  • 模型新增deleted_at字段,用于标记删除时间
  • 重写query方法,所有默认查询都会自动过滤掉deleted_at不为空的记录
  • 调用user.soft_delete()执行软删除,替代原生的db.session.delete(user)

如果不想自己写Mixin,可以直接使用sqlalchemy_utils库的SoftDeleteMixin,它已经封装好了这些逻辑:

from sqlalchemy_utils import SoftDeleteMixin

class User(SoftDeleteMixin, TimestampMixin, db.Model):
    # ... 模型字段定义

3. 时间戳字段(created_at、updated_at)

我们通过TimestampMixin实现了自动管理时间戳:

  • created_at:默认值为当前UTC时间,创建记录时自动赋值
  • updated_at:默认值为当前UTC时间,每次更新记录时自动刷新为当前时间

如果不想用Mixin,也可以直接在模型中定义这两个字段:

class User(db.Model):
    # ... 其他字段
    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:42:42