datamodel-code-generator
datamodel-code-generator copied to clipboard
Prefix with the parent schema object name for inline child schemas with the same name
Is your feature request related to a problem? Please describe. When using the --use-title-as-name flag, inline defined child schemas get a number appended to them because of name conflicts. For example, given the following schema definitions:
MyFirstSchema:
type: object
properties:
payload:
type: object
properties:
status:
type: string
id:
type: string
required:
- status
- id
required:
- payload
MySecondSchema:
type: object
properties:
payload:
type: object
properties:
userName:
type: string
randomField:
type: string
required:
- userName
- randomField
required:
- payload
Running the generator will create the following classes to represent the payload
fields:
class Payload1(BaseModel):
status: str
id: str
class MyFirstSchema(BaseModel):
payload: Payload1
class Payload2(BaseModel):
userName: str
randomField: str
class MySecondSchema(BaseModel):
payload: Payload2
These are hard to instantiate / use in code because they have no specific meaning and are inside the same module. Even worse, a new spec can cause the numbers to change which causes additive changes to unexpectedly be breaking.
Describe the solution you'd like In these name conflict scenarios, I think it would be best to choose the parent schema's name as a prefix. For example, the payload classes would become:
class MyFirstSchemaPayload(BaseModel):
status: str
id: str
class MySecondSchemaPayload(BaseModel):
userName: str
randomField: str
This could be applied recursively, using the parent field name whenever a conflict occurs.
Describe alternatives you've considered I've looked into having the OpenAPI spec use references instead of inline definitions, but it is itself being generated from code and adding behavior to support references would likely be more complex than this change. I am using this library for context.
I met similar issue on generated class name when I use multiple jsonschema files as described below. below case is fixed by using the jsonschema file (path) as the "parent" of each definition(generating class).
the case I met: there are two jsonschema file, and one extends the other definition as below:
$ ls /work/*
/work/v1/schema.json # original definition
/work/v2/schema.json # extending the above definition
/work/v1/schema.json:
{
"definitions": {
"First": {
"properties": {
"first": {
"type": "string"
}
},
"required": [
"first"
]
},
"Target": {
"allOf": [
{
"$ref": "#/definitions/First"
},
{
"properties": {
"attr_original": {
"type": "integer"
}
},
"required": [
"attr_original"
]
}
]
}
}
}
/work/v2/schema.json:
{
"definitions": {
"Target": {
"allOf": [
{
"$ref": "/work/v1/schema.json#/definitions/Target"
},
{
"properties": {
"attr_added_in_v2": {
"type": "array",
"items": {
"type": "integer"
}
}
},
"required": [
"attr_added_in_v2"
]
}
]
}
}
}
current result I got:
$ datamodel-codegen --input-file-type jsonschema --input /work/v2/schema.json
:
class First(BaseModel):
first: str
class Target(First):
attr_original: int
class Target1(Target): # numbering suffix
attr_added_in_v2: List[int]
desired result is:
:
class V1SchemaTarget(First): # prefix with the parent ( based jsonschema file path)
attr_original: int
class Target(V1SchemaTarget):
attr_added_in_v2: List[int]
refer #1300 for naming of 'class Target(V1SchemaTarget)' .
Any solution on this?