Open GC-Elia opened 9 months ago
@GC-Elia
Being able to access pydantic v2 model properties directly such as model.item_id and not model.root.item_id.
How do we access to root attribute without root
attribute?
I think RootModel provides a root
attribute to access the content.
RootModel is the feature of pydantic. datamodel-code-generator is not owened. https://docs.pydantic.dev/latest/concepts/models/#rootmodel-and-custom-root-types
You may want Type Adapter
to parse the object.
https://docs.pydantic.dev/latest/concepts/type_adapter/
...
InventoryAdapter = TypeAdapter(Union[InventoryItem1, InventoryItem2])
print(InventoryAdapter.validate_python({'item-id': '123'}).item_id)
# 123
Hi @koxudaxi,
This change seem to have been introduced in https://github.com/koxudaxi/datamodel-code-generator/pull/1682 as previously oneOf
generated both fields as Optional
, albeit it was not enforcing the oneOf
requirement, direct field access was supported (model.item_id
).
Other than breaking behavior, I believe it also introduces inconsistency in the generated models where some support direct field access and others not.
Meanwhile I've modified RootModel.jinja2
(simple addition as seen below) to support direct field access, and I wonder if this is something that may be added by default to retain previous behavior, or if you see any downside with this approach.
def __getattr__(self, attr: str):
return getattr(self.root, attr)
@GC-Elia
This change seem to have been introduced in https://github.com/koxudaxi/datamodel-code-generator/pull/1682 as previously oneOf generated both fields as Optional,
I'm sorry. The implementation at this time was completely wrong. It does not follow the correct oneof definition because all the attributes of multiple models are implemented as optional.
Other than breaking behavior, I believe it also introduces inconsistency in the generated models where some support direct field access and others not.
I agree with you. It is true that breaking change should be avoided as much as possible, but due to Python and Pydantic restrictions on rootModel and .root attributes, it would be difficult to reproduce the exact same structure as OpenAPI.
Meanwhile I've modified RootModel.jinja2 (simple addition as seen below) to support direct field access, and I wonder if this is something that may be added by default to retain previous behavior, or if you see any downside with this approach.
Doesn't this hack completely destroy the type-checking mechanism?
I believe it also introduces inconsistency in the generated models where some support direct field access and others not.
It is indeed inconsistent from this point of view, but from the type-checking point of view, it can check if the root model definitely exists, and type checking also shows that there is a union set up within it.
Long story short, it means that you should run the IDE type-chekcing or mypy before you run the code.
Describe the bug Given the following OpenAPI yaml:
And the following generation commands:
The resulted model is:
The following action fails:
While the following succeeds:
Or using the following generation command for pydantic v1 models
The resulted model is:
The following action fails:
Expected behavior Being able to access pydantic v2 model properties directly such as
model.item_id
and notmodel.root.item_id
.Version: