我正在使用棉花糖对JSON字符串进行序列化和反序列化。从棉花糖API文档(https://marshmallow.readthedocs.io/en/3.0/api_reference.html)中,您似乎已经指定了字段的列表(并且,除非使用Meta
,否则为其数据类型。例如:
Marital_Status=Fields.Str()
Employer=Fields.Str()
ContactInfo(data) #where ContactInfo is a class not shown here
但是,我已经有一个JSON模式,用于指定字段和数据类型。例如:
the_template_schema={
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"properties": {
"Marital_Status": {
"$id": "#/properties/Marital_Status",
"type": "string",
"title": "The Marital_status Schema",
"default": "",
"examples": [
"Married"
],
"pattern": "^(.*)$"
}
"Employer": {
"$id": "#/properties/Employer",
"type": "string",
"title": "The Employer Schema",
"default": "",
"examples": [
"Roivant"
],
"pattern": "^(.*)$"
}
}
}
我的问题
我想根据提供的模式数据,指定棉花糖使用的字段。像这样:
fields.magicmethod(the_template_schema)
ContactInfo(data)
这可能吗?如果可以,怎么办?
答案 0 :(得分:1)
在棉花糖中,应将模式指定为Python代码中的类(请参见此处的示例:https://marshmallow.readthedocs.io/en/3.0/quickstart.html#declaring-schemas)。
对于您的情况,可能看起来像
from marshmallow import Schema, fields
class ContactInfoSchema(Schema):
Marital_Status=Fields.Str()
Employer=Fields.Str()
您需要使用棉花糖吗?如果您的模式已经以json-schema格式存在,则可以使用json.load
加载对象,并使用jsonschema
模块针对该模式进行验证。
https://medium.com/python-pandemonium/json-the-python-way-91aac95d4041
答案 1 :(得分:1)
您可以编写自己的转换器,该转换器将采用JSON模式并从中创建动态棉花糖模式。
这是一个示例(它不是JSONSchema,而是更简单的东西)。
from marshmallow import Schema, fields
from functools import partial
def validator(valid_values, input):
if input in valid_values:
return True
return False
def get_type(param_type):
if param_type == "String":
return fields.String
if param_type == "Boolean":
return fields.Boolean
def gen_schema(cls_name, params):
fields = {}
for p in params:
field_type = get_type(p["type"])
if p.get("valid_values"):
fields[p["name"]] = field_type(validate=partial(validator, p["valid_values"]))
else:
fields[p["name"]] = field_type()
schema = type(cls_name, (Schema,), fields)
return schema
class ParameterSchema(Schema):
name = fields.String(required=True)
description = fields.String(required=False)
required = fields.Bool(default=False)
type = fields.String(required=True)
valid_values = fields.List(fields.String, required=False)
p = [
{"name": "filename",
"description": "Should be a filename",
"required": True,
"type": "String",
"valid_values": ["hello.txt", "foo.py", "bar.png"]
},
{"name": "SomeBool",
"description": "Just a bool",
"required": True,
"type": "Boolean",
},
{"name": "NotRequiredBool",
"description": "Another bool thats not required",
"required": False,
"type": "Boolean"
}
]
req1 = {"filename": "foo.py", "SomeBool": False}
req2 = {"filename": "hi.txt", "SomeBool": True, "NotRequiredBool": False}
schema = ParameterSchema()
params1 = schema.load(p, many=True)
dynamic_schema = gen_schema("D1", params1.data)()
dynamic_res1 = dynamic_schema.load(req1)
dynamic_res2 = dynamic_schema.load(req2)
print(dynamic_res1)
print(dynamic_res2)
运行此打印:
UnmarshalResult(data={'filename': 'foo.py', 'SomeBool': False}, errors={})
UnmarshalResult(data={'NotRequiredBool': False, 'SomeBool': True}, errors={'filename': ['Invalid value.']})
您只需更改gen_schema
即可接受有效的JSONSchema,而不是我在此处编写的简单JSONSchema。
希望有帮助。