datamodel-code-generator
datamodel-code-generator copied to clipboard
Multiple pattern properties are not handled correctly
Describe the bug
JSON schema pattern properties can provide multiple patterns where any object property key must match one of the patterns. This is probably not handled correctly by models generated from such a schema.
To Reproduce
Example schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Foo",
"type": "object",
"properties": {
"bar": {
"type": "object",
"patternProperties": {
"^A_\\d$": {
"type": "string"
},
"^B_\\d$": {
"type": "string"
}
}
}
}
}
Used commandline:
$ datamodel-codegen --input tests/data/jsonschema/pattern_properties.json
Expected behavior The given command should generate a model that handles this example data:
{
"bar": {
"A_1": "a",
"B_2": "b"
}
}
However, it will fail with the following error message:
pydantic.error_wrappers.ValidationError: 2 validation errors for Foo
bar -> __key__
string does not match regex "^A_\d$" (type=value_error.str.regex; pattern=^A_\d$)
bar -> __key__
string does not match regex "^B_\d$" (type=value_error.str.regex; pattern=^B_\d$)
Version:
- OS: Ubuntu 20.04
- Python version: 3.8.10
- datamodel-code-generator version: 0.11.15
Additional context Add any other context about the problem here.
I added a reproduction case in #663 .
I have asked in https://github.com/samuelcolvin/pydantic/discussions/3561 how to handle this in Pydantic.
So the generator comes up with something like
class Foo(BaseModel):
bar: Optional[
Union[
Dict[constr(regex=r'^A_\d$'), str],
Dict[constr(regex=r'^B_\d$'), str],
]
] = None
However, the correct way is
class Foo(BaseModel):
bar: Optional[
Dict[
Union[constr(regex=r'^A_\d$'), constr(regex=r'^B_\d$')],
str,
]
] = None
So Union
inside Dict
, not the other way around. I'll try to come up with a fix for that.
Nevermind. This only works for the case where all keys the same type str
.
@georgms Thank you for creating PR and the issue.
Nevermind. This only works for the case where all keys the same type str.
We should discuss the best way in the pydantic project.
no response :(