Flask-SQLAlchemy列默认值根据其他列计算生成

420 阅读1分钟

需求描述

使用Flask-SQLAlchemy定义表类的时候,包含下面两列:

字段名称说明
sfzh身份证号
xb性别

其中性别列想要设置默认值根据身份证号列中数值倒数第二位的数字奇偶类别生成.

实现代码

def get_xb(context):
    """
    判断性别
    Args:
        context:

    Returns:

    """
    sfzh = context.get_current_parameters()['sfzh']
    xb_value = int(sfzh[-2:-1])
    if xb_value % 2 == 0:
        sex = '女'
    else:
        sex = '男'

    return sex

# 定义users用户表
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(11))
    password = db.Column(db.String(100))
    
    sfzh = db.Column(db.String(18))  # 身份证号
    xb = db.Column(db.String(1), default=get_xb)  # 性别,默认值从身份证号中计算   
    

这里在定义User类之前先定义了get_xb(context)函数,其中context.get_current_parameters()['sfzh']写法可以将其他列中的数据拿过来用.

定义列的时候使用default=get_xb就可以了,这里需要注意的是等号后面要跟的是函数名称,不能加()

添加混合(Hybrid)列属性

想要增加新的一列,该列中的数据由其他列计算而来,但并不需要像普通列一样在数据库中生成,可以使用@hybrid_property装饰器来实现,下面定义了一个根据身份证号计算当前年龄的方法,然后在User对象类中增加了使用该方法即时计算到的年龄属性列nl

def get_nl(sfzh):
    """
    计算年龄
    Args:
        sfzh: 身份证号

    Returns:

    """
    birth_year = sfzh[6:10]
    birth_month = sfzh[10:12]
    birth_day = sfzh[12:14]
    from datetime import date
    today = date.today()
    born = date(int(birth_year), int(birth_month), int(birth_day))
    age = today.year - born.year - ((today.month, today.day) < (born.month, born.day))
    return age


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(11))
    password = db.Column(db.String(100))
    
    sfzh = db.Column(db.String(18))  # 身份证号
    xb = db.Column(db.String(1), default=get_xb)  # 性别,默认值从身份证号中计算  
    
    # 添加混合列(并不在数据库中真实存在)
    @hybrid_property
    def nl(self):
        return get_nl(self.sfzh) 

参考SQLAlchemy官方文档: docs.sqlalchemy.org/en/14/core/…