微型模式实现
tinyschema的Python项目详细描述
功能
- 模式定义
- 模式验证
- 数据验证
模式定义
模式定义的方式如下所示。
importtinyschemaastclassPoint(t.Schema):x=t.column(t.IntegerField)y=t.column(t.IntegerField)z=t.column(t.IntegerField,required=False)
使用点访问访问字段,就像一个普通的python对象。但是 返回的对象由字段对象包装。
Field对象具有这些成员。
- name–字段名称(系统值)
- value–字段值
所以这个点模式访问下面这样的字段。
pt = Point(x=10, y=20) print(pt.x.name) # => x print(pt.x.value) # => 10
添加量
schema的一列可以存储favirote值。下面的例子是 存储了一个关于css类“hidden”的值。和添加标签选项 为人类显示表达式(显示值)。
classPoint(t.Schema):x=t.column(t.IntegerField,label=u"x-coordinate",class_="hidden")pt=Point(x=10,y=20)print(pt.x.label)# => x-coordinateprint(pt.x.class_)# => "hidden"
模式验证
架构具有架构验证行为。架构验证是格式检查。
- 仅筛选预期值。
- 正在检查值的类型。
- 如果需要,转换值。
params={"x":"10","y":"20","foo":"foo"}pt=Point.fromdict(params)print(pt.validate())# => OrderedDict([('x', 10), ('y', 20), ('z', None)])
架构验证通过调用validate()方法运行。在上面的代码中, “foo”值不是点架构的成员,因此验证的值不 包含值名foo。z列有required=false选项, 因此,传递的值没有值名z, 转换后的值为“无”。
当发现架构错误时。
当架构验证失败时,将引发失败异常。
params={"x":"aa"}pt=Point.fromdict(params)pt.validate()# tinyschema.Failure: <Failure errors=defaultdict(<class 'list'>, {'y': ['required'], 'x': ['aa is not int']})>
添加字段验证
添加字段验证示例如下(使用验证器之一)
classSignal(t.Schema):color=t.column(t.TextField,t.OneOf(["red","blue","yellow"]))# success versionsignal=Signal(color="red")data=signal.validate()print(data["color"])# => "red"# failure versiontry:signal2=Signal(color="green")data=signal2.validate()exceptt.Failurease:print(e)# <Failure errors=defaultdict(<class 'list'>, {'color': ['green is not in red, blue, yellow']})>
下面是默认验证器。
- any、regex、email、range、length、one of、subset、url
字段的默认类型。
- integerfield、floatfield、booleanfield、textfield、choicesfield、positiveintegerfield
更复杂的结构
Tinyschema支持更复杂的结构,如dict树、序列, 或者一个的组合。
dict树(使用容器)
schema的字段也是schema。下面的示例中,pair schema有两个 成员L和R,L和R是一个点模式。
classPair(t.Schema):l=t.column(t.Container(Point),class_="left")r=t.column(t.Container(Point),class_="right")params={"l":{"x":"10","y":"20","foo":"foo"},"r":{"x":"100","y":"20"},}pair=Pair.fromdict(params)importpprintpprint.pprint(pair.validate())# {'l': OrderedDict([('x', 10), ('y', 20), ('z', None)]),# 'r': OrderedDict([('x', 100), ('y', 20), ('z', None)])}pair.l.value.x.name# => xpair.l.value.x.value# => 10
序列(使用集合)
点列表是点的序列。
classPointList(t.Schema):points=t.column(t.Collection(Point))params={"points":[{"x":"10","y":"20"},{"x":"20","y":"20"},{"x":"30","y":"20"},]}plist=PointList.fromdict(params)importpprintpprint.pprint(plist.validate())# {'points': [OrderedDict([('x', 10), ('y', 20), ('z', None)]),# OrderedDict([('x', 20), ('y', 20), ('z', None)]),# OrderedDict([('x', 30), ('y', 20), ('z', None)])]}
数据验证
数据验证是检查每个数据之间的关系。
(待办事项:温和的例子)
fromtinyschema.datavalidationimportValidationObject,multi,Invalid,single,shareclassPointValidation(ValidationObject):def__init__(self,limit):self.limit=limit@multi(["x","z"])defequals(self,x,z):ifx!=z:raiseInvalid("not equal")@share(single("x"),single("y"),single("z"))deflimit(self,value):ifvalue>self.limit:raiseInvalid("too large")validate=PointValidation(limit=100)print(validate(Point(x=10,y=20)))# => OrderedDict([('x', 10), ('y', 20), ('z', None)])print(validate(Point(x=10,y=20,z=10)))# => OrderedDict([('x', 10), ('y', 20), ('z', 10)])print(validate(Point(x=10,y=20,z=1000)))# tinyschema.Failure: <Failure errors=defaultdict(<class 'list'>, {'z': ['too large'], 'x': ['not equal']})>print(validate(Point(x="aa")))# tinyschema.Failure: <Failure errors=defaultdict(<class 'list'>, {'x': ['aa is not int'], 'y': ['required']})>