datamodel-code-generator
datamodel-code-generator copied to clipboard
Enum fields generate default value using string type instead of enum causing pydantic serializer warning
Describe the bug A generated model with an enum field generates its default value using string type instead of enum value causes pydantic serializer warnings:
.../env/lib/python3.10/site-packages/pydantic/main.py:477: UserWarning: Pydantic serializer warnings:
Expected `enum` but got `str` with value `'synced'` - serialized value may not be as expected
return self.__pydantic_serializer__.to_json(
The model output is:
status: Optional[Status] = Field("synced", title="Status")
Manually updating the model output to the following fixes the warning:
status: Optional[Status] = Field(Status.synced, title="Status")
To Reproduce
Example schema:
"components": {
"schemas": {
"settings.Setting": {
"type": "object",
"properties": {
"status": {
"title": "Status",
"type": "string",
"enum": [
"uninitialized",
"synced",
"pending",
"dispatched"
],
"default": "synced"
},
}
}
}
}
Used commandline alternative:
codegen.generate(
SCHEMA_FILE,
output=BASE_MODEL_OUTPUT_DIR,
input_file_type=codegen.InputFileType.OpenAPI,
output_model_type=codegen.DataModelType.PydanticV2BaseModel,
target_python_version=codegen.PythonVersion.PY_310,
base_class="sdk.ProjectBaseModel",
custom_file_header=file_header,
use_schema_description=True,
use_field_description=True,
use_subclass_enum=True,
use_double_quotes=True,
openapi_scopes=[codegen.OpenAPIScope.Schemas]
)
Expected behavior
Output the model with field as:
status: Optional[Status] = Field(Status.synced, title="Status")
Version:
- OS: Ubuntu 22.04
- Python version: 3.10
- datamodel-code-generator version: 0.28.4
Not sure why this is not the default behaviour, but you can get what you expect by using the --set-default-enum-member flag.
Thanks @kjagiello . The output is super close to what I need, but it generates an incorrect module path to the enum for me.
Without --set-default-enum-member:
# models/settings.py
class Status(StrEnum):
pending = "pending"
accepted = "accepted"
class Setting(BaseModel):
...
status: Optional[Status] = Field("accepted")
With --set-default-enum-member:
# models/settings.py
class Status(StrEnum):
pending = "pending"
accepted = "accepted"
class Setting(BaseModel):
...
status: Optional[Status] = Field(settings.Status.accepted)
From within the settings.py file, the path settings.Status.accepted is invalid and should have been just Status.accepted.