如何修复使用datamodel-codegen生成Pydantic V2模型时的序列化警告?
datamodel-codegen生成Pydantic模型警告问题解析
警告内容
Expected `Union[list[definition-ref], definition-ref, bool]` but got `JsonSchemaObject` - serialized value may not be as expected Expected `Union[definition-ref, bool]` but got `JsonSchemaObject` - serialized value may not be as expected Expected `Union[definition-ref, bool]` but got `JsonSchemaObject` - serialized value may not be as expected Expected `Union[definition-ref, bool]` but got `JsonSchemaObject` - serialized value may not be as expected return self.__pydantic_serializer__.to_python(
复现信息
输入文件pets.json
{ "pets": [ { "name": "dog", "age": 2 }, { "name": "cat", "age": 1 }, { "name": "snake", "age": 3, "nickname": "python" } ], "status": 200 }
执行命令
datamodel-codegen --input pets.json --input-file-type json --output model.py
使用版本
python - 3.11.4 pydantic==2.1.1 datamodel-code-generator==0.21.4 genson==1.2.2
警告含义
这些警告说明:datamodel-codegen生成的JSON Schema结构和Pydantic 2.x序列化器的预期不匹配。Pydantic期望Schema中使用定义引用(definition-ref)、布尔值或这类类型的列表来复用结构,但实际生成的是完整的内联JsonSchemaObject,这会导致序列化/反序列化的结果可能不符合预期。
触发原因
当直接用原始JSON作为输入时,datamodel-codegen会调用genson生成JSON Schema。genson对数组内的相似对象会生成内联的Schema结构,而不会提取公共类型并用$ref引用。Pydantic 2.x的序列化器针对引用式Schema做了优化,遇到内联结构时就会抛出这类警告。
修复方法
手动编写JSON Schema:先定义复用的类型,再用
$ref引用。比如编写如下pets_schema.json:{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "pets": { "type": "array", "items": { "$ref": "#/definitions/Pet" } }, "status": { "type": "integer" } }, "definitions": { "Pet": { "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "nickname": { "type": "string" } }, "required": ["name", "age"] } } }再执行命令生成模型:
datamodel-codegen --input pets_schema.json --input-file-type jsonschema --output model.py升级datamodel-codegen版本:将datamodel-code-generator升级到0.25.0及以上版本,新版本对Pydantic 2.x的兼容性更好,能自动处理这类内联结构的问题,避免警告。
手动修改生成的模型:生成模型后,将内联的结构提取为独立的Pydantic模型。比如原生成的模型中
pets字段可能是List[dict[str, Any]]或内联的BaseModel,可以手动改成:from pydantic import BaseModel from typing import List, Optional class Pet(BaseModel): name: str age: int nickname: Optional[str] = None class Model(BaseModel): pets: List[Pet] status: int
可能引发的问题
- 序列化/反序列化时数据结构异常,比如可选字段的默认值、验证规则不符合预期。
- 生成的模型代码冗余,重复定义相似结构,后期维护成本高。
- 极端场景下可能导致Pydantic验证失败,或者序列化后的JSON与原始输入不一致。
内容的提问来源于stack exchange,提问作者shaik moeed
相关产品推荐
相关产品推荐

