Skip to content

数据模型(Model) ​

数据模型是模块开发的第一步,用于定义数据库表结构。项目使用 SQLAlchemy ORM,模型类通过继承基类自动获得通用字段和方法。

文件位置 ​

src/modules/system/position/models.py

完整代码 ​

以下为 src/modules/system/position/models.py 的核心代码(省略版权头):

python
"""
岗位模型模块
=============================================================

提供岗位管理的数据模型定义,用于定义员工岗位信息。

企业级特性:
    1. 使用枚举类管理状态常量,确保类型安全
    2. 状态文本自动转换,便于前端展示
    3. 便捷的查询方法,提高开发效率
    4. 继承 BaseModel 和 BaseDB,复用通用功能
    5. __init__ 由 BaseModel 统一管理,无需重复定义
"""

from enum import IntEnum
from typing import Optional, List

from src.common.base_db import BaseDB
from src.common.base_model import BaseModel
from config import DB_PREFIX
from sqlalchemy import text
from src.core.database import db
from src.common.utils.request import like_contains


# ============================================================
# 岗位状态枚举
# ============================================================

class PositionStatus(IntEnum):
    """
    岗位状态枚举

    使用 IntEnum 确保类型安全,避免魔法数字。
    可直接用于数据库查询和比较。
    """
    DISABLED = 0  # 停用
    ENABLED = 1  # 启用


# ============================================================
# 岗位模型
# ============================================================

class Position(BaseModel, BaseDB):
    """
    岗位模型

    用于存储员工岗位信息,如:技术总监、产品经理等。
    继承自 BaseModel(通用字段)和 BaseDB(数据库操作方法)。
    """

    # 表名:使用配置前缀 + 模型名
    __tablename__ = DB_PREFIX + "position"
    __table_comment__ = "岗位表"

    # ============================================================
    # 字段定义
    # ============================================================

    # 岗位名称:必填字段,最长255字符
    name = db.Column(
        db.String(255),
        nullable=False,
        index=True,
        comment="岗位名称"
    )

    # 岗位状态:使用枚举确保类型安全
    # 默认值为停用,创建后需手动启用
    status = db.Column(
        db.Integer,
        index=True,
        default=PositionStatus.DISABLED,
        server_default=text('0'),
        comment="岗位状态:0-停用 1-启用"
    )

    # 岗位排序:数值越小越靠前
    sort = db.Column(
        db.Integer,
        default=0,
        server_default=text('0'),
        comment="岗位排序"
    )

    # ============================================================
    # 注意:__init__ 方法在 BaseModel 中已实现,无需重复定义
    # BaseModel 已处理驼峰转换、字段过滤等逻辑
    # ============================================================

    # ============================================================
    # 便捷属性
    # ============================================================

    @property
    def status_text(self) -> str:
        """获取岗位状态文本:将数字状态转换为可读的中文文本"""
        status_map = {
            PositionStatus.DISABLED: '停用',
            PositionStatus.ENABLED: '启用'
        }
        return status_map.get(self.status, '未知')

    @property
    def is_enabled(self) -> bool:
        """判断岗位是否启用"""
        return self.status == PositionStatus.ENABLED

    @property
    def is_disabled(self) -> bool:
        """判断岗位是否停用"""
        return self.status == PositionStatus.DISABLED

    # ============================================================
    # 自定义查询方法
    # ============================================================

    @classmethod
    def get_enabled(cls) -> List['Position']:
        """获取所有启用的岗位,按排序值升序排列"""
        return cls.query.filter(
            cls.is_delete == 0,
            cls.status == PositionStatus.ENABLED
        ).order_by(cls.sort.asc()).all()

    @classmethod
    def get_by_name(cls, name: Optional[str]) -> Optional['Position']:
        """根据岗位名称精确查询"""
        if not name:
            return None
        return cls.query.filter(
            cls.name == name,
            cls.is_delete == 0
        ).first()

    def __repr__(self) -> str:
        return f'岗位:{self.name}'

代码解析 ​

基类继承 ​

python
class Position(BaseModel, BaseDB):
基类来源提供能力
BaseModelsrc/common/base_model.py通用字段:id、create_user、create_time、update_user、update_time、is_delete
BaseDBsrc/common/base_db.pysave() 持久化方法(仅 flush,不 commit)、to_dict() 序列化方法

状态枚举 ​

项目推荐使用 IntEnum 管理状态常量,避免魔法数字:

python
class PositionStatus(IntEnum):
    DISABLED = 0  # 停用
    ENABLED = 1  # 启用
值含义
0停用 / 禁用
1启用 / 在用

软删除字段 is_delete 由基类提供:0 = 正常,1 = 已删除。

字段定义风格 ​

项目使用 db.Column(从 src.core.database 导入的 db 实例),而非直接导入 Column:

python
from src.core.database import db

name = db.Column(db.String(255), nullable=False, index=True, comment="岗位名称")

表名配置 ​

python
__tablename__ = DB_PREFIX + "position"

DB_PREFIX 从 .env 读取(默认 flask_),最终表名为 flask_position。

开发要点 ​

  1. 业务字段仅定义差异部分:通用字段(id、时间、软删除等)由基类自动提供
  2. 表名必须加 DB_PREFIX 前缀:保持命名一致性
  3. 使用 db.Column 而非直接导入 Column:保持与项目一致的导入风格
  4. 状态字段使用 IntEnum:避免魔法数字,提高代码可读性
  5. 同时设置 default 和 server_default:确保 ORM 和直 SQL 两种场景都能正确赋默认值
  6. __init__ 由 BaseModel 统一管理:无需在子类中重复定义

总结 ​

数据模型继承 BaseModel(公共字段)和 BaseDB(save 方法),表名必须加 DB_PREFIX 前缀。状态字段使用 IntEnum 枚举类管理,字段定义使用 db.Column 风格。__init__ 由 BaseModel 统一处理驼峰转换和字段过滤,子类无需重复定义。

小蚂蚁云团队 · 提供技术支持