Open boh5 opened 2 years ago
I found that:
hero
object from request body by function fastapi.dependencies.utils.request_body_to_args
, and actually generate hero
by this line v_, errors_ = field.validate(value, values, loc=loc)
sqlmodel.SQLModel.validate
. In this function, transform alias dict value
to field name dict values
by values, fields_set, validation_error = validate_model(cls, value)
, then init model by model = cls(**values)
Hero
model allow_population_by_field_name = True
, so model = cls(**values)
can not init correctllyallow_population_by_field_name = True
on Hero
model, then it works, hero
object contains the filed secret_name
with value string
hero: Hero
to hero: HeroPydantic
, v_, errors_ = field.validate(value, values, loc=loc)
can init correctly. But I can't step into pydantic.ModelField.validate
in debugger of pycharm-2022.1.3. So I can't find the reason why pydantic and sqlmodel have different results@boh5 Do you have solution about this problem? I use the latest version and I still have this problem.
Facing the same issue here
Would be amazing to get this addressed, if possible. It's blocking us from adopting this project.
Looks like there is an open PR to fix this: https://github.com/tiangolo/sqlmodel/pull/774#issuecomment-1883904625
Looks like there is an open PR to fix this: #774 (comment)
I think this PR will only partially fix this issue. It will allow a workaround using validation_alias
but does not address the issue that alias
keyword does not behave the same way as the Pydantic Field alias
when it comes to validating models.
Do we know if this issue is on the radar to be addressed?
Facing a similar issue here, the alias is not taken into account when generating the body for the request.
I am also using pydantic's v2 alias_generator
, and it works if alias
is not defined in the field.
If the alias
is passed, the body doesn't apply the alias_generator
and ignores aliases completely.
I tried to work around the same issue but I ended with a similar bug.
validation_alias
works to set the field and store the data, but retrieval is not working properly. serialization_alias
calls the default_factory
.
E.g.:
class MyModel(SQLModel):
since: datetime = Field(
description="Begin of the interval",
default_factory=date_factory(),
sa_type=DateTime,
index=True,
alias="from",
title="from",
schema_extra={"validation_alias": "from", "serialization_alias": "from"}
)
SQLModel is supposed to expand pydantic contract instead of superseding it.
I hope for the prompt resolution because this bug prevents overcoming Python language limitations and limits API expression capabilities.
Minimum Error Example:
from sqlmodel import SQLModel, Field
from typing import Optional
class SimpleBookChapter(SQLModel):
class Config:
populate_by_name = True
chapter_number: int = Field(alias="episode_number")
title: Optional[str] = Field(alias="episode_title")
chapter_data = {"episode_number": 1, "episode_title": "Test Chapter"}
chapter = SimpleBookChapter.model_validate(chapter_data)
print(chapter)
error log:
chapter = SimpleBookChapter.model_validate(chapter_data)
File "D:\ProgramData\Anaconda3\envs\chapchat\lib\site-packages\sqlmodel\main.py", line 848, in model_validate
return sqlmodel_validate(
File "D:\ProgramData\Anaconda3\envs\chapchat\lib\site-packages\sqlmodel\_compat.py", line 314, in sqlmodel_validate
cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 2 validation errors for SimpleBookChapter
chapter_number
Field required [type=missing, input_value={'episode_number': 1, 'ep..._title': 'Test Chapter'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.8/v/missing
title
Field required [type=missing, input_value={'episode_number': 1, 'ep..._title': 'Test Chapter'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.8/v/missing
success example:
from pydantic import Field
from sqlmodel import SQLModel
from typing import Optional
class SimpleBookChapter(SQLModel):
class Config:
populate_by_name = True
chapter_number: int = Field(alias="episode_number")
title: Optional[str] = Field(alias="episode_title")
chapter_data = {"episode_number": 1, "episode_title": "Test Chapter"}
chapter = SimpleBookChapter.model_validate(chapter_data)
print(chapter)
success log:
chapter_number=1 title='Test Chapter'
from pydantic import Field
It's work for me :)
I was facing a similar problem where I wanted to have camel case fields for the endpoints, but snake case for the code and the database column. I solved overriding the Config class.
from sqlmodel import Field, SQLModel
from humps import camelize
def to_camel(string):
return camelize(string)
class MyModel(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
my_field : str
class Config: # type: ignore
populate_by_name = True
alias_generator = to_camel
It worked but it remains the problem with the typechecking ("Config" overrides symbol of same name in class "SQLModel")
First Check
Commit to Help
Example Code
Description
Hero
model, thesecret_name
field aliased tosecretName
hero.secret_name
isNone
hero: Hero
tohero: HeroPydantic
, thehero.secret_name
can get correct value from post data. But the strainge thing is that I can get correcthero.secret_name
byhero: Hero = Hero.parse_obj(hero.dict(by_alias=True))
So it seems that alias argument in sqlmodel seems not working for converting body from post data, I have to write two models in order to achieve that.
Operating System
Windows
Operating System Details
No response
SQLModel Version
0.0.6
Python Version
3.7.6
Additional Context
No response