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 = ""
m.dvalue = "not a date"
上一篇:WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]


下一篇:linux----LAMP之编译安装apache