python 模式至少有一个键

问题描述 投票:0回答:3

我正在使用

schema
库。

如何创建一个模式来验证字典中是否包含任何键和相应的值?

mydict_schema = Schema({
    Optional('name'): str,
    Optional('name_id'): int,
})

目前钥匙都是

Optional
,但我希望至少有一个。

python validation dictionary schema associative-array
3个回答
0
投票

背景

  • python2
  • 使用模式库进行验证

用例

  • DevSyedK 想要创建一个模式验证约束,要求字典在一组可能的键中至少有一个键
  • DevSyedK 当前有一个
    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] )
    
    
另请参阅

  • 如何找到列表交集?

0
投票
我也遇到了这个问题,所以发布一个解决方案以供将来参考。实现此目的的一种方法是创建具有一些自定义逻辑的子类。

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'}
    

0
投票

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'])
    
© www.soinside.com 2019 - 2024. All rights reserved.