From 6afa9673b2841fe8b1e1ab5ab414b179d77ccc25 Mon Sep 17 00:00:00 2001 From: stickm4n Date: Sun, 1 Dec 2024 22:20:48 +0100 Subject: [PATCH 1/5] Add compatibility for Pydantic V2 regex (renamed param from regex to param) --- sqlmodel/main.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index 3532e81a8e..b263e43491 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -240,6 +240,7 @@ def Field( max_length: Optional[int] = None, allow_mutation: bool = True, regex: Optional[str] = None, + pattern: Optional[str] = None, discriminator: Optional[str] = None, repr: bool = True, primary_key: Union[bool, UndefinedType] = Undefined, @@ -285,6 +286,7 @@ def Field( max_length: Optional[int] = None, allow_mutation: bool = True, regex: Optional[str] = None, + pattern: Optional[str] = None, discriminator: Optional[str] = None, repr: bool = True, primary_key: Union[bool, UndefinedType] = Undefined, @@ -339,6 +341,7 @@ def Field( max_length: Optional[int] = None, allow_mutation: bool = True, regex: Optional[str] = None, + pattern: Optional[str] = None, discriminator: Optional[str] = None, repr: bool = True, sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore @@ -374,6 +377,7 @@ def Field( max_length: Optional[int] = None, allow_mutation: bool = True, regex: Optional[str] = None, + pattern: Optional[str] = None, discriminator: Optional[str] = None, repr: bool = True, primary_key: Union[bool, UndefinedType] = Undefined, @@ -389,6 +393,12 @@ def Field( schema_extra: Optional[Dict[str, Any]] = None, ) -> Any: current_schema_extra = schema_extra or {} + + if IS_PYDANTIC_V2: + current_schema_extra.update(pattern=pattern or regex) + else: + current_schema_extra.update(regex=regex or pattern) + field_info = FieldInfo( default, default_factory=default_factory, @@ -411,7 +421,6 @@ def Field( min_length=min_length, max_length=max_length, allow_mutation=allow_mutation, - regex=regex, discriminator=discriminator, repr=repr, primary_key=primary_key, From 5de3c0b1b02d4c2b173d682b669167e1831da72c Mon Sep 17 00:00:00 2001 From: "Julio C. Galindo" <54072664+stickM4N@users.noreply.github.com> Date: Sat, 30 Aug 2025 13:15:22 +0200 Subject: [PATCH 2/5] Add test for field regex/pattern parameter --- tests/test_pydantic/test_field.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_pydantic/test_field.py b/tests/test_pydantic/test_field.py index 9d7bc77625..b1a4a08295 100644 --- a/tests/test_pydantic/test_field.py +++ b/tests/test_pydantic/test_field.py @@ -55,3 +55,17 @@ class Model(SQLModel): instance = Model(id=123, foo="bar") assert "foo=" not in repr(instance) + + +@pytest.mark.parametrize("param", ["regex", "pattern"]) +def test_field_regex_param(param: str): + class DateModel(SQLModel): + date_1: str = Field(**{param: r"^\d{2}-\d{2}-\d{4}$"}) + date_2: str = Field(schema_extra={param: r"^\d{2}-\d{2}-\d{4}$"}) + + DateModel(date_1="12-31-2024", date_2="12-31-2024") + # Validates correctly + + with pytest.raises(ValidationError): + DateModel(date_1="2024-12-31", date_2="2024-12-31") + # This should raise a ValueError due to regex mismatch From 926bd788b1498782c9fae71f3a9f5e981cb752b1 Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Tue, 7 Oct 2025 21:13:45 +0200 Subject: [PATCH 3/5] Split test case with `VaidationError` into two --- tests/test_pydantic/test_field.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_pydantic/test_field.py b/tests/test_pydantic/test_field.py index b1a4a08295..f2e4ced5cd 100644 --- a/tests/test_pydantic/test_field.py +++ b/tests/test_pydantic/test_field.py @@ -67,5 +67,7 @@ class DateModel(SQLModel): # Validates correctly with pytest.raises(ValidationError): - DateModel(date_1="2024-12-31", date_2="2024-12-31") - # This should raise a ValueError due to regex mismatch + DateModel(date_1="incorrect", date_2="12-31-2024") # date_1 pattern mismatch + + with pytest.raises(ValidationError): + DateModel(date_1="12-31-2024", date_2="incorrect") # date_2 pattern mismatch From f45a40f4aecd3a7536d16de8d40e0fba004509bd Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Tue, 7 Oct 2025 21:34:17 +0200 Subject: [PATCH 4/5] Fix failing test --- sqlmodel/main.py | 8 ++++++-- tests/test_pydantic/test_field.py | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index b263e43491..20f430ea67 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -395,9 +395,13 @@ def Field( current_schema_extra = schema_extra or {} if IS_PYDANTIC_V2: - current_schema_extra.update(pattern=pattern or regex) + current_schema_extra.update( + pattern=pattern or regex or current_schema_extra.get("pattern") + ) else: - current_schema_extra.update(regex=regex or pattern) + current_schema_extra.update( + regex=regex or pattern or current_schema_extra.get("pattern") + ) field_info = FieldInfo( default, diff --git a/tests/test_pydantic/test_field.py b/tests/test_pydantic/test_field.py index f2e4ced5cd..bbdf212627 100644 --- a/tests/test_pydantic/test_field.py +++ b/tests/test_pydantic/test_field.py @@ -61,13 +61,13 @@ class Model(SQLModel): def test_field_regex_param(param: str): class DateModel(SQLModel): date_1: str = Field(**{param: r"^\d{2}-\d{2}-\d{4}$"}) - date_2: str = Field(schema_extra={param: r"^\d{2}-\d{2}-\d{4}$"}) - DateModel(date_1="12-31-2024", date_2="12-31-2024") - # Validates correctly + DateModel(date_1="12-31-2024") # Validates correctly - with pytest.raises(ValidationError): - DateModel(date_1="incorrect", date_2="12-31-2024") # date_1 pattern mismatch + +def test_field_pattern_via_schema_extra(): + class DateModel(SQLModel): + date_1: str = Field(schema_extra={"pattern": r"^\d{2}-\d{2}-\d{4}$"}) with pytest.raises(ValidationError): - DateModel(date_1="12-31-2024", date_2="incorrect") # date_2 pattern mismatch + DateModel(date_1="incorrect") From 91e8e7eb6e7c4b107ebcafe216e712aeae60dfaf Mon Sep 17 00:00:00 2001 From: "Julio C. Galindo" <54072664+stickM4N@users.noreply.github.com> Date: Mon, 13 Oct 2025 01:04:22 +0200 Subject: [PATCH 5/5] Remove unused ignore comment --- sqlmodel/ext/asyncio/session.py | 2 +- sqlmodel/orm/session.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sqlmodel/ext/asyncio/session.py b/sqlmodel/ext/asyncio/session.py index 54488357bb..ff99dff899 100644 --- a/sqlmodel/ext/asyncio/session.py +++ b/sqlmodel/ext/asyncio/session.py @@ -129,7 +129,7 @@ async def exec( ``` """ ) - async def execute( # type: ignore + async def execute( self, statement: _Executable, params: Optional[_CoreAnyExecuteParams] = None, diff --git a/sqlmodel/orm/session.py b/sqlmodel/orm/session.py index dca4733d61..9e82d48a73 100644 --- a/sqlmodel/orm/session.py +++ b/sqlmodel/orm/session.py @@ -113,7 +113,7 @@ def exec( """, category=None, ) - def execute( # type: ignore + def execute( self, statement: _Executable, params: Optional[_CoreAnyExecuteParams] = None,