From: Yurii Motov Date: Wed, 28 Jan 2026 17:41:42 +0000 (+0100) Subject: Add `alias_priority` param to Field, add tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f37dcb98918136bcf670b7a1659d38ee87321e0e;p=thirdparty%2Ffastapi%2Fsqlmodel.git Add `alias_priority` param to Field, add tests --- diff --git a/sqlmodel/main.py b/sqlmodel/main.py index 84478f24..2b82fc20 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -3,6 +3,7 @@ from __future__ import annotations import builtins import ipaddress import uuid +import warnings import weakref from collections.abc import Mapping, Sequence, Set from datetime import date, datetime, time, timedelta @@ -207,6 +208,7 @@ def Field( *, default_factory: Optional[NoArgAnyCallable] = None, alias: Optional[str] = None, + alias_priority: Optional[int] = None, validation_alias: Optional[str] = None, serialization_alias: Optional[str] = None, title: Optional[str] = None, @@ -250,6 +252,7 @@ def Field( *, default_factory: Optional[NoArgAnyCallable] = None, alias: Optional[str] = None, + alias_priority: Optional[int] = None, validation_alias: Optional[str] = None, serialization_alias: Optional[str] = None, title: Optional[str] = None, @@ -302,6 +305,7 @@ def Field( *, default_factory: Optional[NoArgAnyCallable] = None, alias: Optional[str] = None, + alias_priority: Optional[int] = None, validation_alias: Optional[str] = None, serialization_alias: Optional[str] = None, title: Optional[str] = None, @@ -335,6 +339,7 @@ def Field( *, default_factory: Optional[NoArgAnyCallable] = None, alias: Optional[str] = None, + alias_priority: Optional[int] = None, validation_alias: Optional[str] = None, serialization_alias: Optional[str] = None, title: Optional[str] = None, @@ -371,11 +376,21 @@ def Field( schema_extra: Optional[dict[str, Any]] = None, ) -> Any: current_schema_extra = schema_extra or {} + + for param_name in ( + "alias_priority", + ): + 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) + # Extract possible alias settings from schema_extra so we can control precedence schema_validation_alias = current_schema_extra.pop("validation_alias", None) schema_serialization_alias = current_schema_extra.pop("serialization_alias", None) + current_alias_priority = alias_priority or current_schema_extra.pop("alias_priority", None) field_info_kwargs = { "alias": alias, + "alias_priority": current_alias_priority, "title": title, "description": description, "exclude": exclude, diff --git a/tests/test_pydantic/test_field.py b/tests/test_pydantic/test_field.py index 140b02fd..4906eb76 100644 --- a/tests/test_pydantic/test_field.py +++ b/tests/test_pydantic/test_field.py @@ -2,7 +2,7 @@ from decimal import Decimal from typing import Literal, Optional, Union import pytest -from pydantic import ValidationError +from pydantic import ConfigDict, ValidationError from sqlmodel import Field, SQLModel @@ -54,3 +54,57 @@ def test_repr(): instance = Model(id=123, foo="bar") assert "foo=" not in repr(instance) + + +def test_alias_priority_1(): + def to_camel(string: str) -> str: + return "".join(word.capitalize() for word in string.split("_")) + + class Model(SQLModel): + model_config = ConfigDict(alias_generator=to_camel) + + field: str = Field(alias="field_alias", alias_priority=1) + + m = Model.model_validate({"Field": "value1"}) + assert m.field == "value1" + + with pytest.raises(ValidationError): + Model.model_validate({"field_alias": "value1"}) + + +@pytest.mark.parametrize("alias_priority", [None, 2]) +def test_alias_priority_2(alias_priority: Optional[int]): + def to_camel(string: str) -> str: + return "".join(word.capitalize() for word in string.split("_")) + + class Model(SQLModel): + model_config = ConfigDict(alias_generator=to_camel) + + field: str = Field(alias="field_alias", alias_priority=alias_priority) + + m = Model.model_validate({"field_alias": "value1"}) + assert m.field == "value1" + + with pytest.raises(ValidationError): + Model.model_validate({"Field": "value1"}) + + +def test_alias_priority_via_schema_extra(): # Current workaround. Remove after some time + def to_camel(string: str) -> str: + return "".join(word.capitalize() for word in string.split("_")) + + with pytest.warns( + DeprecationWarning, + match="Pass `alias_priority` parameter directly to Field instead of passing it via `schema_extra`", + ): + + class Model(SQLModel): + model_config = ConfigDict(alias_generator=to_camel) + + field: str = Field(alias="field_alias", schema_extra={"alias_priority": 2}) + + m = Model.model_validate({"field_alias": "value1"}) + assert m.field == "value1" + + with pytest.raises(ValidationError): + Model.model_validate({"Field": "value1"})