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

Null and object field transforms only into object (JsonSchema)

Open ag0n1k opened this issue 3 years ago • 1 comments

Describe the bug In docker-compose json schema there are options like:

"shm_size": {"type": ["number", "string"]},

which transforms into code like:

shm_size: Optional[Union[float, str]] = None

And it's correct! But also there are fields with null (none), like:

"pid": {"type": ["string", "null"]},
...
"network": {
    "type": ["object", "null"],
...

Which transforms into

pid: Optional[Optional[str]] = None
...
networks: Optional[Dict[constr(regex=r'^[a-zA-Z0-9._-]+$'), Network]] = None

As we can see the Nullable variant disappear from the model, and there came the errors like

E           networks -> default
E             none is not an allowed value (type=type_error.none.not_allowed)

But it is!

I expect something like this, which works:

networks: Optional[Dict[constr(regex=r'^[a-zA-Z0-9._-]+$'), Union[Network, None]]] = None

To Reproduce

Example schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "config_schema_v3.7.json",
  "type": "object",
  "required": [
    "networks"
  ],
  "properties": {
    "networks": {
      "id": "#/properties/networks",
      "type": "object",
      "patternProperties": {
        "^[a-zA-Z0-9._-]+$": {
          "$ref": "#/definitions/network"
        }
      }
    }
  },
  "patternProperties": {
    "^x-": {}
  },
  "additionalProperties": false,
  "definitions": {
    "network": {
      "id": "#/definitions/network",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "name": {
          "type": "string"
        }
      },
      "patternProperties": {
        "^x-": {}
      },
      "additionalProperties": false
    }
  }
}

Used commandline:

datamodel-codegen --input compose-test.json --input-file-type jsonschema --output compose_test_model.py

Expected behavior

d = Model(**{
    "networks": {
        "external": {"name": "Allow none"},
        "default": None
    }
})

pydantic.error_wrappers.ValidationError: 1 validation error for Model
networks -> default
  none is not an allowed value (type=type_error.none.not_allowed)

Expected in generation:

networks: Dict[constr(regex=r'^[a-zA-Z0-9._-]+$'), Union[Network, None]]

Version:

  • OS: MacOS 11.5.1
  • Python version: 3.9.4
  • datamodel-code-generator version: 0.11.14

Additional context Add any other context about the problem here.

ag0n1k avatar Oct 19 '21 15:10 ag0n1k

Also, it's happened with objects types, e.g.

        "external": {
          "type": ["boolean", "object"],

This is also tranform only into an object and boolean variant not allowed.

    external: Optional[Union[External, bool]] = None
vs
    external: Optional[External] = None

ag0n1k avatar Oct 19 '21 15:10 ag0n1k

@ag0n1k I'm sorry for my too-late reply.
I have released the PR as 0.15.0 Thank you very much!!

koxudaxi avatar Jan 04 '23 16:01 koxudaxi