schema
库。
如何创建一个模式来验证字典中是否包含任何键和相应的值?
mydict_schema = Schema({
Optional('name'): str,
Optional('name_id'): int,
})
目前钥匙都是
Optional
,但我希望至少有一个。
ZeroOrMore
约束,但 DevSyedK 希望它成为 OneOrMore
约束True
lstkeys_possible = ['alpha','bravo','charlie'] lstkeys_actual = [] ## 不会验证 lstkeys_actual = ['zulu'] ## 不会验证 lstkeys_actual = ['alpha'] ## 将验证 架构( lambda vinput: bool(set(vinput[0]) & set(vinput[1])) ).validate( [lstkeys_possible,lstkeys_actual] )
class AtLeastOneSchema(Schema):
one_required = {'name', 'name_id'}
def validate(self, data, **kwargs):
val_schema = Schema(
self.schema,
self._error,
self._ignore_extra_keys,
self._name,
self._description,
self.as_reference,
)
# This part validates your schema like normal
# required to avoid recursive calls to this exact
# validate method
rv = val_schema.validate(data, **kwargs)
# Now to the custom logic to ensure one of the keys exists
e = self._error
found_one = False
for key in data:
if key in self.one_required:
found_one = True
if not found_one:
message = (
f"Missing key from {self.one_required}"
)
raise SchemaError(message, e.format(data) if e else None)
return rv
现在您可以使用新的子类创建模式
mydict_schema = AtLeastOneSchema({
Optional('name'): str,
Optional('name_id'): int,
Optional(str): str # so that you can add any other arbitrary data
})
使用示例:
>>> good_data = {'name': "john"}
>>> mydict_schema.validate(good_data)
{'name': 'john'}
>>> bad_data = {"foo": "bar"}
>>> mydict_schema.validate(bad_data)
Traceback (most recent call last):
schema.SchemaError: Missing key from {'name', 'name_id'}
Use
函数允许使用当前正在验证的数据调用函数。
And
函数允许依次验证两个或多个构造。结合这些,您可以定义一个函数来验证“运行中”的数据,并在您对所看到的内容不满意时引发异常:
from schema import Schema, Optional, Use, And, SchemaMissingKeyError
def validate_mydict_schema(data):
if not len(data):
raise SchemaMissingKeyError("specify at least one of 'name' and 'name_id'")
return data
mydict_schema = Schema(And({
Optional('name'): str,
Optional('name_id'): int
}, Use(validate_mydict_schema)))
>>> mydict_schema.validate({})
SchemaError: specify at least one of 'name' and 'name_id'
>>> mydict_schema.validate({"name": "John"})
{'name': 'John'}
真正酷的一件事是您甚至可以修改数据。例如,您可以在仅给出“name_id”的情况下查找“name”并返回它,以便始终保证验证结果也包含“name”键。
def validate_mydict_schema(data):
if not len(data):
raise SchemaMissingKeyError("one of keys 'name' and 'name_id' is required")
if "name" not in data:
data["name"] = "insert lookup using data['name_id'] here..."
return data
>>> mydict_schema.validate({"name_id": 1}).keys()
dict_keys(['name_id', 'name'])