✨ Support `pattern` parameter
I faced this issue with Pydantic V2 and there is a simple workaround to it by passing the pattern Field parameter as schema extra:
Ex:
class MyClass(SQLModel)
id: str = Field(unique=True, schema_extra={'pattern': r"^\d{5}$"})
I don't know if this issue was already fixed in another branch, I saw there was a temporary PR already made but closed.
@tiangolo @alejsdev or some other maintainer... could you please review this issue?
Thanks for the PR! We're going through the backlog of PRs right now, and will get back to you once we've had the time to review this and consider the (breaking) change 🙏
@svlandeg Nice to hear you are taking action on this matter. There is remark, the parameter the was renamed between Pydantic v1 and v2 is regex-> pattern, not as listed in the PR.
The suggestion I made in the PR was to keep both versions compatible when upgrading, but there is an alternative, which is not managing the change between them and just provide the proper type hints.
If you want me to update the PR just let me know, IDK which approach is more adequate for the project.
@stickM4N, could you please clarify why this should be treated as breaking change?
Apart from that, should we add a test for new parameter?
Hi @YuriiMotov, nice to hear from you again. Sorry for not have given a better description for the problem, but here it is:
from sqlmodel import SQLModel, Field
class MyClass(SQLModel):
id: str = Field(unique=True, pattern=r"^\d{5}$")
This code raises TypeError: Field() got an unexpected keyword argument 'pattern' which is the intended keyword for pydantic.v2.FieldInfo, differet from regex for pydantic.v1.FieldInfo
The aim of this PR is to make them compatible and have the same logic for both version sqlmodel-wise
I have other proposition that is more comfortable to work with in my opinion, but its more of a change... and its to convert schema_extra param to **schema_extra, so the input from sqlmodel.Field is more flexible, should not have impacts in other places and it add flexibility to implementations and simpler way to migrate from pydantic.Field to sqlmodel.Field
Since we still support regex parameter and just add alias (pattern) and make it working with Pydantic V2, I wouldn't call these changes braking.
So, I would remove the mention of breaking.
Also, I think we should mark regex as deprecated and prioritize pattern over regexp regardless the version of Pydantic.
Still we need to add some test:
- pass
regexand validate valid\invalid value - pass
patternand validate valid\invalid value - pass both
regexandpatternand see thatpatternis used - don't pass
patterndirectly, but passschema_extra={"pattern": r"..."}(workaround that is currently being used to make it working with Pydantic V2) - it should still work
Noted @YuriiMotov, I will do that. Here there is the reference to the removed parameter and error raise associated to it. Here is its implementation.
I would like to propose the following change:
def Field(default, *, ..., **schema_extra)
rather than
def Field(default, *, ..., schema_extra)
I would like to propose the following change:
def Field(default, *, ..., **schema_extra)
I think this should be done in a separate PR. And I would do it in a different way - I would add pydantic_kwargs and json_schema_extra parameters and deprecate schema_extra.
Could you please address other ideas from this comment?
I think this should be done in a separate PR. And I would do it in a different way - I would add
pydantic_kwargsandjson_schema_extraparameters and deprecateschema_extra. Fine by me!
Since we still support
regexparameter and just add alias (pattern) and make it working with Pydantic V2, I wouldn't call these changes braking. So, I would remove the mention of breaking.
Regarding this, I would still label it as breaking because pydantic.v2 does not support the keyarg and will raise an error if provided. You can check the docs and the implementation for farther details.
Tests
- [x] pass
regexand validate valid\invalid value. - [x] pass
patternand validate valid\invalid value. - [ ] ~pass both
regexandpatternand see thatpatternis used~ -> this is implicitly tested because if itsV1pattern will not work and if itsV2the test will raise an error. - [x] don't pass
patterndirectly, but passschema_extra={"pattern": r"..."}(workaround that is currently being used to make it working with Pydantic V2) -> kept for compatibility, might be removed in the future
Regarding this, I would still label it as breaking because pydantic.v2 does not support the keyarg and will raise an error if provided. You can check the docs and the implementation for farther details.
I still can't get it.. Could you please share a code example that works in current version (0.0.24) but will be broken after applying changes from this PR?
I still can't get it.. Could you please share a code example that works in current version (0.0.24) but will be broken after applying changes from this PR?
No, it will break now, after migrating from pydantic.v1 to pydantic.v2 without changing parameters from Field(...). This PR will provide a solution for that rather than create an incompatibility.
Maybe i misunderstood the label breaking meaning.
No, it will break now, after migrating from
pydantic.v1topydantic.v2without changing parameters fromField(...). This PR will provide a solution for that rather than create an incompatibility. Maybe i misunderstood the labelbreakingmeaning.
So, it's not breaking. Breaking changes is when new changes brake old user's code that worked without errors previously
So, it's not breaking. Breaking changes is when new changes brake old user's code that worked without errors previously
Noted! Thanks
Tests currently fail because new Pydantic version has been released and caused linting errors. See: https://github.com/fastapi/sqlmodel/pull/1591
Thanks! I think we should wait for #1035 to be reviewed by Sebastian and merged, then reflect those changes in this PR. So, let's wait a bit