mirror of
https://github.com/fastapi/sqlmodel.git
synced 2026-03-13 09:29:54 +08:00
Allow AliasChoices and AliasPath for validation_alias in Field
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
__version__ = "0.0.31"
|
||||
|
||||
# Re-export from Pydantic
|
||||
from pydantic import AliasChoices as AliasChoices
|
||||
from pydantic import AliasPath as AliasPath
|
||||
|
||||
# Re-export from SQLAlchemy
|
||||
from sqlalchemy.engine import create_engine as create_engine
|
||||
from sqlalchemy.engine import create_mock_engine as create_mock_engine
|
||||
|
||||
@@ -22,7 +22,7 @@ from typing import (
|
||||
overload,
|
||||
)
|
||||
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from pydantic import AliasChoices, AliasPath, BaseModel, EmailStr
|
||||
from pydantic.fields import FieldInfo as PydanticFieldInfo
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
@@ -207,7 +207,7 @@ def Field(
|
||||
*,
|
||||
default_factory: Optional[NoArgAnyCallable] = None,
|
||||
alias: Optional[str] = None,
|
||||
validation_alias: Optional[str] = None,
|
||||
validation_alias: Union[str, AliasPath, AliasChoices, None] = None,
|
||||
serialization_alias: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
@@ -250,7 +250,7 @@ def Field(
|
||||
*,
|
||||
default_factory: Optional[NoArgAnyCallable] = None,
|
||||
alias: Optional[str] = None,
|
||||
validation_alias: Optional[str] = None,
|
||||
validation_alias: Union[str, AliasPath, AliasChoices, None] = None,
|
||||
serialization_alias: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
@@ -302,7 +302,7 @@ def Field(
|
||||
*,
|
||||
default_factory: Optional[NoArgAnyCallable] = None,
|
||||
alias: Optional[str] = None,
|
||||
validation_alias: Optional[str] = None,
|
||||
validation_alias: Union[str, AliasPath, AliasChoices, None] = None,
|
||||
serialization_alias: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
@@ -335,7 +335,7 @@ def Field(
|
||||
*,
|
||||
default_factory: Optional[NoArgAnyCallable] = None,
|
||||
alias: Optional[str] = None,
|
||||
validation_alias: Optional[str] = None,
|
||||
validation_alias: Union[str, AliasPath, AliasChoices, None] = None,
|
||||
serialization_alias: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from typing import Union
|
||||
from typing import Optional, Union
|
||||
|
||||
import pytest
|
||||
from pydantic import AliasChoices as PAliasChoices
|
||||
from pydantic import AliasPath as PAliasPath
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from pydantic import Field as PField
|
||||
from sqlmodel import Field, SQLModel
|
||||
from sqlmodel import AliasChoices, AliasPath, Field, SQLModel
|
||||
|
||||
"""
|
||||
Alias tests for SQLModel and Pydantic compatibility
|
||||
@@ -99,10 +101,22 @@ def test_json_by_alias(
|
||||
|
||||
class PydanticUserV2(BaseModel):
|
||||
first_name: str = PField(validation_alias="firstName", serialization_alias="f_name")
|
||||
second_name: Optional[str] = PField(
|
||||
default=None, validation_alias=PAliasChoices("secondName", "surname")
|
||||
)
|
||||
nickname: Optional[str] = PField(
|
||||
default=None, validation_alias=PAliasPath("names", 2)
|
||||
)
|
||||
|
||||
|
||||
class SQLModelUserV2(SQLModel):
|
||||
first_name: str = Field(validation_alias="firstName", serialization_alias="f_name")
|
||||
second_name: Optional[str] = Field(
|
||||
default=None, validation_alias=AliasChoices("secondName", "surname")
|
||||
)
|
||||
nickname: Optional[str] = Field(
|
||||
default=None, validation_alias=AliasPath("names", 2)
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", [PydanticUserV2, SQLModelUserV2])
|
||||
@@ -113,6 +127,27 @@ def test_create_with_validation_alias(
|
||||
assert user.first_name == "John"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", [PydanticUserV2, SQLModelUserV2])
|
||||
def test_create_with_validation_alias_alias_choices(
|
||||
model: Union[type[PydanticUserV2], type[SQLModelUserV2]],
|
||||
):
|
||||
user = model.model_validate({"firstName": "John", "secondName": "Doe"})
|
||||
assert user.second_name == "Doe"
|
||||
|
||||
user2 = model.model_validate({"firstName": "John", "surname": "Doe"})
|
||||
assert user2.second_name == "Doe"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", [PydanticUserV2, SQLModelUserV2])
|
||||
def test_create_with_validation_alias_alias_path(
|
||||
model: Union[type[PydanticUserV2], type[SQLModelUserV2]],
|
||||
):
|
||||
user = model.model_validate(
|
||||
{"firstName": "John", "names": ["John", "Doe", "Johnny"]}
|
||||
)
|
||||
assert user.nickname == "Johnny"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", [PydanticUserV2, SQLModelUserV2])
|
||||
def test_serialize_with_serialization_alias(
|
||||
model: Union[type[PydanticUserV2], type[SQLModelUserV2]],
|
||||
|
||||
Reference in New Issue
Block a user