схема дуршлага для отображения, где ключи являются переменными, а значения-массивами
Как определить схему в дуршлаге для JSON следующего вида?
{
'data' : {
'key_1' : [123, 567],
'key_2' : ['abc','def'],
'frank_underwood' : [666.66, 333.333],
... etc ...
}
}
Ключи внутри "data" могут быть любой строкой, а значения-массивами.
В настоящее время у меня есть следующее, Но это действительно не накладывает никаких ограничений на типы значений, которые может иметь отображение.
class Query(colander.MappingSchema):
data = colander.SchemaNode(
colander.Mapping(unknown='preserve'),
missing={}
)
Как правильно это описать?
3 ответов:
Возможным решением является использованиепользовательского валидатора .
Вот полный рабочий пример пользовательского валидатора, который проверяет, являются ли все значения произвольной карты сингулярно типизированными массивами.
import colander def values_are_singularly_typed_arrays(node, mapping): for val in mapping.values(): if not isinstance(val, list): raise colander.Invalid(node, "one or more value(s) is not a list") if not len(set(map(type, val))) == 1: raise colander.Invalid(node, "one or more value(s) is a list with mixed types") class MySchema(colander.MappingSchema): data = colander.SchemaNode( colander.Mapping(unknown='preserve'), validator=values_are_singularly_typed_arrays ) def main(): valid_data = { 'data' : { 'numbers' : [1,2,3], 'reals' : [1.2,3.4,5.6], } } not_list = { 'data' : { 'numbers' : [1,2,3], 'error_here' : 123 } } mixed_type = { 'data' : { 'numbers' : [1,2,3], 'error_here' : [123, 'for the watch'] } } schema = MySchema() schema.deserialize(valid_data) try: schema.deserialize(not_list) except colander.Invalid as e: print(e.asdict()) try: schema.deserialize(mixed_type) except colander.Invalid as e: print(e.asdict()) if __name__ == '__main__': main()
Я не знаю насчет дуршлага, но вы могли бы использовать Spyne.
class Data(ComplexModel): key_1 = Array(Integer) key_2 = Array(Unicode) frank_underwood = Array(Double) class Wrapper(ComplexModel): data = DataПолный рабочий пример: https://gist.github.com/plq/3081280856ed1c0515de
Документы модели Спайна: http://spyne.io/docs/2.10/manual/03_types.html
Однако, оказывается, это не то, что вам нужно. Если вам нужен более свободно заданный словарь, то вам нужно прибегнуть к использованию пользовательского типа:class DictOfUniformArray(AnyDict): @staticmethod # yes staticmethod def validate_native(cls, inst): for k, v in inst.items(): if not isinstance(k, six.string_types): raise ValidationError(type(k), "Invalid key type %r") if not isinstance(v, list): raise ValidationError(type(v), "Invalid value type %r") # log_repr prevents too much data going in the logs. if not len(set(map(type, v))) == 1: raise ValidationError(log_repr(v), "List %s is not uniform") return True class Wrapper(ComplexModel): data = DictOfUniformArrayПолный рабочий exaple: https://github.com/arskom/spyne/blob/spyne-2.12.5-beta/examples/custom_type.py
Вот еще один способ, который я нашел.
from colander import SchemaType, Invalid import json class JsonType(SchemaType): ... def deserialize(self, node, cstruct): if not cstruct: return null try: result = json.loads(cstruct, encoding=self.encoding) except Exception as e: raise Invalid(node,"Not json ...") return result
Comments