-
Notifications
You must be signed in to change notification settings - Fork 122
Full Pydantic 2.0 Support + Bug Fixes #691
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
base: main
Are you sure you want to change the base?
Conversation
It seems like the |
Wow, @sethbuff thanks for this contribution. I'll review this week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Let's use this to do a 1.0.0 beta release, which gives us more room to make the breaking changes this PR introduces. Also, dropping Pydantic 1 compatibility aligns well with a more stable release version of redis-om-python.
Using 1.0.0-beta will also give us some time to explore required updates to docs and a migration guide.
@@ -1,6 +1,6 @@ | |||
[tool.poetry] | |||
name = "redis-om" | |||
version = "0.3.5" | |||
version = "0.4.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this 1.0.0-beta.
# for vector, full text search, and sortable fields, we always have to index | ||
# We could require the user to set index=True, but that would be a breaking change | ||
return ( | ||
getattr(field_info, "index", False) is True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see individual fields can still opt out of indexing (unless the field type implies that we have to index). That makes sense. I might expand this later to add a warning if index on the field is False but it's an index-required type.
When upgrading to pydantic 2.0, we ran into many issues. It seemed like anything outside of a very simple implementation would not work.
We believed initially that we had to remove support for pydantic 1.0 to fix all of these. Now, we see it might be possible to still allow for compatibility across both versions but there are other breaking changes proposed so we just left it as we felt it would be best.
The main issues we initially faced were:
test_model_validate_uses_default_values
)model_fields_set
was not accurate which resulted in anything that relied onexclude_unset=True
to not workcontext
object that can be passed in when validating a model was being set toNone
KNNExpression
was expectingscore_field
to be aModelField
which was removed in 2.0 and would result in anAttributeError
if usedWe were also using pydantic in ways that weren't supported and there was a lot of implicit behavior that changed that was not covered in any documentation or the migration guide. That was the core of a lot these issues.
To fix 1, we added
field
to theredis-om
FieldInfo
object so we have access to the field name everywhere and we don't have to rely onalias
. (candidly, this also made some refactoring on our side much easier)To fix 2 and 3, we took inspiration from sqlmodel and allowed for explicitly setting when to "index" a model (similar to
table=True
insqlmodel
). This means that we only set the class attributes to anExpressionProxy
once, which fixed the default errors. This was happening because pydantic was reading theExpressionProxy
set on fields further up in the inheritance tree and thinking it was the default value. This is a breaking change but with how pydantic 2.0 works, we feel it makes the most sense. It also creates an easy way to preventredis-om
models that won't be queried from being indexed.For 4, we believe requiring pydantic 2.0 (also a breaking change) and using the new
field_validator
decorator to validatepk
fixed this issue.For 5, we upgraded the
KNNExpression
to allow for a little more flexibility and updated it to use theredis-om
FieldInfo
class with name.EDIT:
We also found an issue where certain fields that were inherited where unintentionally being indexed because the
FieldInfo
object defaults theredis-om
values toPydanticUndefined
which istruthy
. The part that generated the index just checked ifindex
wastruthy
and would index if it was.