Skip to content

Is it possible to have a schema with no $ref references ? #889

@neimad1985

Description

@neimad1985

Versions:

  • OS: Ubuntu 18.04
  • Python: 3.7.4
  • Pydantic: 0.32.2

Hi,

First of all a huge thanks for the great work done on this package, glad that you are reaching version 1.0 soon !

I have the following simple models: a car and an engine, a car holds an engine.

from pydantic import BaseModel

class Engine(BaseModel):
    size: int

class Car(BaseModel):
    engine: Engine

If I print the car's schema I get this:

print(Car.schema_json(indent=4, sort_keys=True))

# >>> {
#     "definitions": {
#         "Engine": {
#             "properties": {
#                 "size": {
#                     "title": "Size",
#                     "type": "integer"
#                 }
#             },
#             "required": [
#                 "size"
#             ],
#             "title": "Engine",
#             "type": "object"
#         }
#     },
#     "properties": {
#         "engine": {
#             "$ref": "#/definitions/Engine"
#         }
#     },
#     "required": [
#         "engine"
#     ],
#     "title": "Car",
#     "type": "object"
# }

I would prefer very much to have this, a recursive engine schema inside the car's one:

# >>> {
#     "definitions": {},
#     "properties": {
#         "engine": {
#             "properties": {
#                 "size": {
#                     "title": "Size",
#                     "type": "integer"
#                 }
#             },
#             "required": [
#                 "size"
#             ],
#             "title": "Engine",
#             "type": "object"
#         }
#     },
#     "required": [
#         "engine"
#     ],
#     "title": "Car",
#     "type": "object"
# }

The pydantic documentation states that:

“sub-models” with modifications (via the Schema class) like a custom title, description or default value, are recursively included instead of referenced.

So I tried and modified my code by using the Schema class to trigger something but still did not obtain what I wanted:

from pydantic import BaseModel
from pydantic import Schema

class Engine(BaseModel):
    size: int = Schema(..., title="a size")

class Car(BaseModel):
    engine: Engine = Schema(..., title="an engine")

print(Car.schema_json(indent=4, sort_keys=True))

# >>> {
#     "definitions": {
#         "Engine": {
#             "properties": {
#                 "size": {
#                     "title": "a size",
#                     "type": "integer"
#                 }
#             },
#             "required": [
#                 "size"
#             ],
#             "title": "Engine",
#             "type": "object"
#         }
#     },
#     "properties": {
#         "engine": {
#             "allOf": [
#                 {
#                     "$ref": "#/definitions/Engine"
#                 }
#             ],
#             "title": "an engine"
#         }
#     },
#     "required": [
#         "engine"
#     ],
#     "title": "Car",
#     "type": "object"
# }

Instead I got a "allOf" in the car's schema which I do not understand and still no recursive engine schema.

My question is: is it possible to achieve what I want ? No definitions sections, just recursive schemas.

I know I could have some problems with cross referencing schemas (A referencing B and B referencing A), but I do not care of this detail since I know my schemas do not have this kind of thing.

Did I miss or misunderstood something in the documentation (which I read several times) ?
I even tried to inspect pydantic's code to find an answer but the section (schema.py) which generates the schemas is a bit too complicated for me.

Thank you for your time and go on with the greak work :)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions