You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
If I use pydantic_queryset_creator, I get a Pydantic RootModel of type List. Normally, if I call model_json_schema of a RootModel, the originating model name is referenced in $defs. But if I use pydantic_queryset_creator, the model name is always leaf in the produced json schema. Additionaly, if I specify a name when calling pydantic_queryset_creator, this name will be used for the type of object that is in the array and also for the array itself, that makes no sense for me. It is a bit hard to explain for me, so I provided some example code with additional comments that I hope will be enough to understand what I meen. If not, please ask!
I also rewrote pydantic_queryset_creator to match my desired behaviour, but maybe I completely get the function wrong. Maybe it also breaks something with pydantic_model_creator, that is for to complex for me to fully understand.
this is for explaining what I was expecting from pydantic_queryset_creator:
classPet(BaseModel): # <-- normal BaseModelid: intclassPets(RootModel[list[Pet]]): # <-- normal RootModel
...
# RootModel, like it is generated in pydantic_queryset_creatorPetsGenerated=create_model(f"{Pet.__name__}_list", __base__=RootModel, root=(list[Pet], Field(default_factory=list)))
and how pydantic_queryset_creator actually behaves:
classPetTortoise(Model): # <-- basic Tortoise Modelid=IntField(pk=True)
...
PetTortoisePydantic=pydantic_model_creator(PetTortoise) # <-- this works finePetTortoiseListPydantic=pydantic_queryset_creator(PetTortoise) # <-- array with "leafs" as itemsPetTortoiseListPydanticWithName=pydantic_queryset_creator(PetTortoise, name=PetTortoise.__name__) # <-- array with "PetTortoise" as title and "PetTortoise" as items
and my slightly modified version of pydantic_queryset_creator:
defpydantic_queryset_creator_patched(
cls: "Type[Model]",
*,
name=None,
submodel_name=None, # <-- introduced option to explicitly name the items of the arrayexclude: tuple[str, ...] = (),
include: tuple[str, ...] = (),
computed: tuple[str, ...] = (),
allow_cycles: Optional[bool] =None,
sort_alphabetically: Optional[bool] =None,
) ->Type[PydanticListModel]:
_submodel_name=submodel_nameorcls.__name__# <-- if not set, use the name of the originating model as name for the submodelsubmodel=pydantic_model_creator(
cls,
exclude=exclude,
include=include,
computed=computed,
allow_cycles=allow_cycles,
sort_alphabetically=sort_alphabetically,
name=_submodel_name,
)
lname=nameorf"{cls.__name__}_list"# Creating Pydantic class for the properties generated beforemodel=create_model(
lname,
__base__=PydanticListModel,
root=(List[submodel], Field(default_factory=list)), # type: ignore
)
# Copy the Model docstring overmodel.__doc__=_cleandoc(cls)
# The title of the model to hide the hash postfixmodel.model_config["title"] =nameorf"{submodel.model_config['title']}_list"model.model_config["submodel"] =submodel# type: ignorereturnmodelPetTortoiseListPydanticPatched=pydantic_queryset_creator_patched(PetTortoise) # <-- array named "PetTortoise_list" with items "PetTortoise"if__name__=="__main__":
print(json.dumps(Pet.model_json_schema(), indent=2))
"""results in: { "properties": { "id": { "title": "Id", "type": "integer" } }, "required": [ "id" ], "title": "Pet", # <-- title is Pet "type": "object" } """
a manually created RootModel, where the title is passed in via RootModel.__name__
print(json.dumps(Pets.model_json_schema(), indent=2))
"""results in: { "$defs": { "Pet": { # <-- the items are of type Pet "properties": { "id": { "title": "Id", "type": "integer" } }, "required": [ "id" ], "title": "Pet", "type": "object" } }, "items": { "$ref": "#/$defs/Pet" }, "title": "Pets", # <-- we are dealing with Pets here "type": "array" } """
If we generate a RootModel like in pydantic_queryset_creator, it works perfectly fine:
Additional context
I want to dynamically build OpenAPI Spec with the definitions provided by model_json_schema of the Pydantic BaseModels generated by pydantic_model_creator and pydantic_queryset_creator. For that, I need to remove all $defs that are referenced in a $ref and store them in #/components/schemas for example. Patching every $ref to point to #/components/schemas can be easily done by providing a ref_template for model_json_schema. But it is not great that every $def of a pydantic list model has "leaf" as a key.
The text was updated successfully, but these errors were encountered:
Describe the bug
If I use
pydantic_queryset_creator
, I get a PydanticRootModel
of typeList
. Normally, if I callmodel_json_schema
of aRootModel
, the originating model name is referenced in $defs. But if I usepydantic_queryset_creator
, the model name is alwaysleaf
in the produced json schema. Additionaly, if I specify a name when callingpydantic_queryset_creator
, this name will be used for the type of object that is in the array and also for the array itself, that makes no sense for me. It is a bit hard to explain for me, so I provided some example code with additional comments that I hope will be enough to understand what I meen. If not, please ask!I also rewrote
pydantic_queryset_creator
to match my desired behaviour, but maybe I completely get the function wrong. Maybe it also breaks something with pydantic_model_creator, that is for to complex for me to fully understand.Example code with additional comments
this is for explaining what I was expecting from
pydantic_queryset_creator
:and how
pydantic_queryset_creator
actually behaves:and my slightly modified version of
pydantic_queryset_creator
:a manually created RootModel, where the title is passed in via
RootModel.__name__
If we generate a RootModel like in
pydantic_queryset_creator
, it works perfectly fine:pydantic_model_creator
works perfectly fine:what is leaf?
title
of items and array are the same:desired behaviour:
Additional context
I want to dynamically build OpenAPI Spec with the definitions provided by model_json_schema of the Pydantic BaseModels generated by pydantic_model_creator and pydantic_queryset_creator. For that, I need to remove all $defs that are referenced in a $ref and store them in #/components/schemas for example. Patching every $ref to point to #/components/schemas can be easily done by providing a ref_template for model_json_schema. But it is not great that every $def of a pydantic list model has "leaf" as a key.
The text was updated successfully, but these errors were encountered: