Skip to content

Commit f37dcb9

Browse files
committed
Add alias_priority param to Field, add tests
1 parent 5611bda commit f37dcb9

2 files changed

Lines changed: 70 additions & 1 deletion

File tree

sqlmodel/main.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import builtins
44
import ipaddress
55
import uuid
6+
import warnings
67
import weakref
78
from collections.abc import Mapping, Sequence, Set
89
from datetime import date, datetime, time, timedelta
@@ -207,6 +208,7 @@ def Field(
207208
*,
208209
default_factory: Optional[NoArgAnyCallable] = None,
209210
alias: Optional[str] = None,
211+
alias_priority: Optional[int] = None,
210212
validation_alias: Optional[str] = None,
211213
serialization_alias: Optional[str] = None,
212214
title: Optional[str] = None,
@@ -250,6 +252,7 @@ def Field(
250252
*,
251253
default_factory: Optional[NoArgAnyCallable] = None,
252254
alias: Optional[str] = None,
255+
alias_priority: Optional[int] = None,
253256
validation_alias: Optional[str] = None,
254257
serialization_alias: Optional[str] = None,
255258
title: Optional[str] = None,
@@ -302,6 +305,7 @@ def Field(
302305
*,
303306
default_factory: Optional[NoArgAnyCallable] = None,
304307
alias: Optional[str] = None,
308+
alias_priority: Optional[int] = None,
305309
validation_alias: Optional[str] = None,
306310
serialization_alias: Optional[str] = None,
307311
title: Optional[str] = None,
@@ -335,6 +339,7 @@ def Field(
335339
*,
336340
default_factory: Optional[NoArgAnyCallable] = None,
337341
alias: Optional[str] = None,
342+
alias_priority: Optional[int] = None,
338343
validation_alias: Optional[str] = None,
339344
serialization_alias: Optional[str] = None,
340345
title: Optional[str] = None,
@@ -371,11 +376,21 @@ def Field(
371376
schema_extra: Optional[dict[str, Any]] = None,
372377
) -> Any:
373378
current_schema_extra = schema_extra or {}
379+
380+
for param_name in (
381+
"alias_priority",
382+
):
383+
if param_name in current_schema_extra:
384+
msg = f"Pass `{param_name}` parameter directly to Field instead of passing it via `schema_extra`"
385+
warnings.warn(msg, DeprecationWarning, stacklevel=2)
386+
374387
# Extract possible alias settings from schema_extra so we can control precedence
375388
schema_validation_alias = current_schema_extra.pop("validation_alias", None)
376389
schema_serialization_alias = current_schema_extra.pop("serialization_alias", None)
390+
current_alias_priority = alias_priority or current_schema_extra.pop("alias_priority", None)
377391
field_info_kwargs = {
378392
"alias": alias,
393+
"alias_priority": current_alias_priority,
379394
"title": title,
380395
"description": description,
381396
"exclude": exclude,

tests/test_pydantic/test_field.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Literal, Optional, Union
33

44
import pytest
5-
from pydantic import ValidationError
5+
from pydantic import ConfigDict, ValidationError
66
from sqlmodel import Field, SQLModel
77

88

@@ -54,3 +54,57 @@ class Model(SQLModel):
5454

5555
instance = Model(id=123, foo="bar")
5656
assert "foo=" not in repr(instance)
57+
58+
59+
def test_alias_priority_1():
60+
def to_camel(string: str) -> str:
61+
return "".join(word.capitalize() for word in string.split("_"))
62+
63+
class Model(SQLModel):
64+
model_config = ConfigDict(alias_generator=to_camel)
65+
66+
field: str = Field(alias="field_alias", alias_priority=1)
67+
68+
m = Model.model_validate({"Field": "value1"})
69+
assert m.field == "value1"
70+
71+
with pytest.raises(ValidationError):
72+
Model.model_validate({"field_alias": "value1"})
73+
74+
75+
@pytest.mark.parametrize("alias_priority", [None, 2])
76+
def test_alias_priority_2(alias_priority: Optional[int]):
77+
def to_camel(string: str) -> str:
78+
return "".join(word.capitalize() for word in string.split("_"))
79+
80+
class Model(SQLModel):
81+
model_config = ConfigDict(alias_generator=to_camel)
82+
83+
field: str = Field(alias="field_alias", alias_priority=alias_priority)
84+
85+
m = Model.model_validate({"field_alias": "value1"})
86+
assert m.field == "value1"
87+
88+
with pytest.raises(ValidationError):
89+
Model.model_validate({"Field": "value1"})
90+
91+
92+
def test_alias_priority_via_schema_extra(): # Current workaround. Remove after some time
93+
def to_camel(string: str) -> str:
94+
return "".join(word.capitalize() for word in string.split("_"))
95+
96+
with pytest.warns(
97+
DeprecationWarning,
98+
match="Pass `alias_priority` parameter directly to Field instead of passing it via `schema_extra`",
99+
):
100+
101+
class Model(SQLModel):
102+
model_config = ConfigDict(alias_generator=to_camel)
103+
104+
field: str = Field(alias="field_alias", schema_extra={"alias_priority": 2})
105+
106+
m = Model.model_validate({"field_alias": "value1"})
107+
assert m.field == "value1"
108+
109+
with pytest.raises(ValidationError):
110+
Model.model_validate({"Field": "value1"})

0 commit comments

Comments
 (0)