[QUESTION] Different attribute names in ORM and Pydantic models?
See original GitHub issueFirst check
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
Description
Hello! I am building an API using FastAPI and would like to have different attribute names across my ORM models and public user-facing resources. For example, here is my ORM User model:
class UserOrm(Base):
id = Column(Integer, primary_key=True)
name = Column(String)
and here is my corresponding Pydantic user model:
class UserResource(BaseModel):
identifier: int
fullname: str
In the public API, I’d like to accept a UserResource object where the attributes are named identifier and fullname. But internally I need some glue that tells FastAPI that identifier
on UserResource
maps to id
on UserOrm
. Is this possible?
I’ve explored doing this differently by defining my UserResource
with an alias on Field like this:
class UserResource(BaseModel):
id: int = Field(alias="identifier")
name: str = Field(alias="fullname")
This lets me accept POST requests from clients where the attributes are named identifier
and fullname
, and my UserResource
request model gets correctly populated, ie id
and name
have the values I’d expect. However when sending an updated UserResource
back to the client, the automatic translation from UserOrm
’s attribute names to the expected aliased attribute names on UserResource
does not happen.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:8
- Comments:6 (1 by maintainers)
Top GitHub Comments
Hi,
the alias parameter defines the public name for the pydantic model. What happens, is that pydantic treats your field name as a private name as soon as you are using an alias. You can change that behavior by setting
allow_population_by_field_name = True
. Your pydantic schema should look like this:Here is the relevant part of the manual: Docs
OK, I find the solution: just add a param
response_model_by_alias=False
to the decorator.