-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Order of keys differs in schema output #7580
Comments
update , i checked the code and the source seems to be pydantic/pydantic/json_schema.py Line 439 in 8f3ac4e
it would be nice to have a flag that also allows non sorted schema output. pydantic/pydantic/json_schema.py Line 389 in 8f3ac4e
Some reasons:
Update: 6043 is where the change to sorting was added. Please consider adding a flag so that the output can be unsorted too. |
Hi @vigneshmanick, Thanks for looking into this! Seems like a reasonable feature request to me. Also related is #7424, enabling sorting for Are you interested in opening a PR to help with this feature request? 😄 |
@sydney-runkle sure, let me give it a try. |
Maybe I’m misunderstanding. The goal is to make json schemas determined to stick in the face of re-factoring. We should be sorting anything that does not have a natural order and keep the natural order on the things that do. Model fields have a natural order so they should never be sorted, if they are that’s a bug. |
Well that's a new test being added right? The goal of sorting is that schema generation is deterministic, e.g. when you migrate from v2 to v3 your tests don't break because the JSON schema output is different. Or if we refactor |
yes, the order of model fields is sorted in the output which is the main issue i have with the schema output. e.g from the issue, |
@sydney-runkle seems like a bug around pydantic/pydantic/json_schema.py Line 2227 in 8f3ac4e
default as a special case...
|
Yep, I'll look into this bug and open a fix. @vigneshmanick, if we don't sort the model fields in the schema, does that eliminate the need for your sorting flag? |
Yes that works for me. |
I think we should just exclude |
That would be great! :) /CC @Galaxy102 |
Sure thing. Can take a look at this after the Thanksgiving holiday 👍. |
Can you please re-open this to reduce the risk of forgetting this? ;) |
Could you provide an example of the schema that you're getting vs the schema that you're expecting when you're using |
Here is a small example to reproduce the bug: from collections import OrderedDict
from typing import Callable
from pydantic import BaseModel, Field, computed_field
MAP = OrderedDict({'2': 'hi', '1': 'hello', '3': 'world'}) # note the ordering
# does not matter if I use a OrderedDict or a normal dict, since dicts are ordered too
class FieldMetaData(BaseModel):
values: Callable[[], dict[str, str]] | None = Field(default=None, exclude=True)
@computed_field
def my_values(self) -> dict[str, str]:
return self.values() if self.values else None
class Bar(BaseModel):
v: str = Field(default='42', json_schema_extra={'extra': FieldMetaData(values=lambda: MAP)})
if __name__ == '__main__':
bar = Bar()
json_schema = bar.model_json_schema()
actual = json_schema['properties']['v']['extra']['my_values']
assert actual == MAP
assert actual.items() == MAP.items()
for k, v in actual.items():
print(k, v)
assert str(actual.items()) == str(MAP.items()) # FAILS because order is wrong |
So in some sense this is a different issue, which is sourced from the following call: pydantic/pydantic/_internal/_generate_schema.py Line 2031 in 667cd37
Which appears to sort the data, which isn't what we want. |
I confirmed sorting happens here: pydantic/pydantic/json_schema.py Line 442 in 667cd37
to_jsonable_python doesn't sort the json_schema_extra.
_sort_json_schema currently avoids sorting some keys based on looking at the parent key, but that doesn't mean anything for schema extras. we could pass extras to that function and then inspect it or it seems easiest jsut to give people an option to opt out of sorting. |
Nice find - any interest in contributing a fix? |
Initial Checks
Description
When a model is specified as a Field and the values are instantiated , the keys are output in sorted order. I would expect that the order of the keys be maintained.
See sample code below. The output of the class
Stepping
when executed standalone isBut when the class
Stepping
is used as a field in another Model and the Field is instantiated then the output of the schema has the values sorted. 'default': {'multi_step': True, 'step': 0.15, 'type': 'const'}}},Is there a setting that would allow the retaining of the field order in the output? Or am i doing something wrong?
Thanks in advance.
Example Code
Python, Pydantic & OS Version
The text was updated successfully, but these errors were encountered: