• sqlalchemy orm数据类型校验的几种方法


    1.在定义ORM模型时校验

    sqlalchemy提供validates函数支持对字段的校验

    from sqlalchemy.orm import validates
    
    class EmailAddress(Base):
        __tablename__ = 'address'
    
        id = Column(Integer, primary_key=True)
        email = Column(String)
    
        @validates('email')
        def validate_email(self, key, address):
            assert '@' in address
            return address

    2.全局校验

    ①.根据sqlalchemy数据类型对应的python_type(注:有些数据类型没有实现python_type这个方法,需重写)

    在进行增改.commit()之前,对传入数据校验.字段的数据类型及是否为空可从已定义好的orm model中获取.

    获取orm信息

    @classmethod
        def orm_fields_info(cls):
            """
            从ORM中获取字段信息
            :param cls:当前资源类
            :type cls:类实例
            :returns: 返回ORM字段类型,字段是否可空
            """
            fields_type = {}
            fields_nullable = {}
            orm_meta = cls.orm_meta
            for prop_name in orm_meta.__dict__:
                prop = getattr(orm_meta, prop_name)
                if isinstance(prop, attributes.InstrumentedAttribute):
                    prop = prop.prop
                    if isinstance(prop, properties.ColumnProperty):
                        fields_type[prop_name] = prop.columns[0].type
                        fields_nullable[prop_name] = prop.columns[0].nullable
            return fields_type, fields_nullable

    根据orm 字段类型的python_type对传入的数据类型进行校验

    def validate_data_type(orm_fields_info, field_name, field_value):
        fields_type, fields_nullable = orm_fields_info
        field_column = fields_type.get(field_name, None)
        if field_column:
            if not (not field_value and fields_nullable[field_name]):
                if hasattr(field_column, 'python_type'):
                    if not isinstance(field_value, field_column.python_type):
                        raise exceptions.ValidationError(attribute=field_name_display,
                             msg=_(
                                 "field [%s] data type didn't match! require [%s],found type [%s]"
                                 % (field_name, field_column.python_type, type(field_value))))

    ②.利用sqlalchemy event创建通用校验器

    from sqlalchemy import Column, Integer, String, DateTime
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import event
    import datetime
    
    Base= declarative_base()
    
    def validate_int(value):
        if isinstance(value, basestring):
            value = int(value)
        else:
            assert isinstance(value, int)
        return value
    
    def validate_string(value):
        assert isinstance(value, basestring)
        return value
    
    def validate_datetime(value):
        assert isinstance(value, datetime.datetime)
        return value
    
    validators = {
        Integer:validate_int,
        String:validate_string,
        DateTime:validate_datetime,
    }
    
    # this event is called whenever an attribute
    # on a class is instrumented
    @event.listens_for(Base, 'attribute_instrument')
    def configure_listener(class_, key, inst):
        if not hasattr(inst.property, 'columns'):
            return
        # this event is called whenever a "set" 
        # occurs on that instrumented attribute
        @event.listens_for(inst, "set", retval=True)
        def set_(instance, value, oldvalue, initiator):
            validator = validators.get(inst.property.columns[0].type.__class__)
            if validator:
                return validator(value)
            else:
                return value
    
    
    class MyObject(Base):
        __tablename__ = 'mytable'
    
        id = Column(Integer, primary_key=True)
        svalue = Column(String)
        ivalue = Column(Integer)
        dvalue = Column(DateTime)
    
    
    m = MyObject()
    m.svalue = "ASdf"
    m.ivalue = "45"
    m.dvalue = "not a date"
  • 相关阅读:
    pycharm2018.1下载激活(mac平台)
    python 保存登录状态 cookie
    utf-8和utf-8-sig的区别
    AcWing 803. 区间合并
    AcWing 801. 二进制中1的个数
    AcWing 800. 数组元素的目标和
    AcWing 799. 最长连续不重复子序列
    AcWing 795. 前缀和
    AcWing 791. 高精度加法 解题记录
    九州缥缈录 合集序言
  • 原文地址:https://www.cnblogs.com/reboot777/p/10304659.html
Copyright © 2020-2023  润新知