datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

Prefix with the parent schema object name for inline child schemas with the same name

Open zlalvani opened this issue 2 years ago • 2 comments

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.

zlalvani avatar Jun 22 '22 21:06 zlalvani

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)' .

itaru2622 avatar May 06 '23 00:05 itaru2622

Any solution on this?

Tomas2D avatar Nov 27 '23 20:11 Tomas2D