如何在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
相关产品推荐
相关产品推荐

