From 159838fc89e577e1c6990188bb945eacb49844c4 Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Wed, 28 Jan 2026 14:11:19 +0100 Subject: [PATCH] Add `deprecated` param to Field, add tests --- sqlmodel/main.py | 9 ++++++++- tests/test_pydantic/test_field.py | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index d9fb652e..7fbfbe57 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -24,6 +24,7 @@ from typing import ( ) from pydantic import BaseModel, EmailStr +from pydantic.fields import Deprecated as Deprecated from pydantic.fields import FieldInfo as PydanticFieldInfo from sqlalchemy import ( Boolean, @@ -213,6 +214,7 @@ def Field( title: Optional[str] = None, description: Optional[str] = None, examples: Optional[list[Any]] = None, + deprecated: Union[Deprecated, str, bool, None] = None, exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, @@ -258,6 +260,7 @@ def Field( title: Optional[str] = None, description: Optional[str] = None, examples: Optional[list[Any]] = None, + deprecated: Union[Deprecated, str, bool, None] = None, exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, @@ -312,6 +315,7 @@ def Field( title: Optional[str] = None, description: Optional[str] = None, examples: Optional[list[Any]] = None, + deprecated: Union[Deprecated, str, bool, None] = None, exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, @@ -347,6 +351,7 @@ def Field( title: Optional[str] = None, description: Optional[str] = None, examples: Optional[list[Any]] = None, + deprecated: Union[Deprecated, str, bool, None] = None, exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, @@ -381,7 +386,7 @@ def Field( ) -> Any: current_schema_extra = schema_extra or {} - for param_name in ("strict", "examples"): + for param_name in ("strict", "examples", "deprecated"): if param_name in current_schema_extra: msg = f"Pass `{param_name}` parameter directly to Field instead of passing it via `schema_extra`" warnings.warn(msg, DeprecationWarning, stacklevel=2) @@ -391,11 +396,13 @@ def Field( schema_serialization_alias = current_schema_extra.pop("serialization_alias", None) current_strict = strict or current_schema_extra.pop("strict", None) current_examples = examples or current_schema_extra.pop("examples", None) + current_deprecated = deprecated or current_schema_extra.pop("deprecated", None) field_info_kwargs = { "alias": alias, "title": title, "description": description, "examples": current_examples, + "deprecated": current_deprecated, "exclude": exclude, "include": include, "const": const, diff --git a/tests/test_pydantic/test_field.py b/tests/test_pydantic/test_field.py index 84758aed..4d6aa86c 100644 --- a/tests/test_pydantic/test_field.py +++ b/tests/test_pydantic/test_field.py @@ -148,3 +148,30 @@ def test_examples_via_schema_extra(): # Current workaround. Remove after some t model_schema = Model.model_json_schema() assert model_schema["properties"]["name"]["examples"] == ["Alice", "Bob"] + + +def test_deprecated(): + class Model(SQLModel): + old_field: str = Field(deprecated=True) + another_old_field: str = Field(deprecated="This field is deprecated") + + model_schema = Model.model_json_schema() + assert model_schema["properties"]["old_field"]["deprecated"] is True + assert model_schema["properties"]["another_old_field"]["deprecated"] is True + + +def test_deprecated_via_schema_extra(): # Current workaround. Remove after some time + with pytest.warns( + DeprecationWarning, + match="Pass `deprecated` parameter directly to Field instead of passing it via `schema_extra`", + ): + + class Model(SQLModel): + old_field: str = Field(schema_extra={"deprecated": True}) + another_old_field: str = Field( + schema_extra={"deprecated": "This field is deprecated"} + ) + + model_schema = Model.model_json_schema() + assert model_schema["properties"]["old_field"]["deprecated"] is True + assert model_schema["properties"]["another_old_field"]["deprecated"] is True -- 2.47.3