简体   繁体   English

创建具有类型化可选值的动态 Pydantic 模型

[英]Create dynamic Pydantic model with typed optional values

I want to create a dynamic model from my data, create JSON from it, and load it in another location.我想从我的数据创建一个动态模型,从中创建 JSON,然后将它加载到另一个位置。

I can't find a way to define a field in a way, that should it is optional, but when data exists for that field - it would be validated.我找不到以某种方式定义字段的方法,如果它是可选的,但是当该字段存在数据时 - 它将被验证。

This is for required field: fields[col_name] = (data_type, None)这是用于必填字段: fields[col_name] = (data_type, None)

# resolve types for data
data_type = resolve_type(data)
required = is_required(data)
if required:
  fields[col_name] = (data_type, ...)
else:
  fields[col_name] = (data_type, None) <--- unclear

...

pydantic.create_model(name, **fields)

The above configuration generates JSON model that makes fields optional and typed, but then I validate by using the input data I can't pass None values - '$.inputs.0.Field', 'message': "None is not of type 'string'"上面的配置生成 JSON 模型,使字段可选和类型化,但随后我使用输入数据进行验证,我无法传递None值 - '$.inputs.0.Field', 'message': "None is not of type 'string'"

So my question - how to declare a field that would validate input, but only when it's not None.所以我的问题 - 如何声明一个可以验证输入的字段,但仅当它不是 None 时。 And in such a manner, that I could create JSON schema and load it in another location.以这种方式,我可以创建 JSON 模式并将其加载到另一个位置。

Implemented workaround based on suggestions in https://github.com/samuelcolvin/pydantic/issues/990根据https://github.com/samuelcolvin/pydantic/issues/990 中的建议实施解决方法

optional_fields = list()
if required:
  fields[col_name] = (data_type, ...)
else:
  fields[col_name] = (data_type, None)
  optional_fields.append(col_name)

model = pydantic.create_model(name, **fields)

def schema_extra(schema, model):
    for column in optional_fields:
        original_type = schema["properties"][column]["type"]
        schema["properties"][column].update({"type": ["null", original_type]})

model.__config__.schema_extra = schema_extra

schema_json = model.schema_json()
Foo = create_model("Foo", foo = (int, None))

Foo(foo=None)
# Foo(foo=None)

Foo()
# Foo(foo=None)

Foo(foo=3)
# Foo(foo=3)

Is this your desired result?这是你想要的结果吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM