question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] Different attribute names in ORM and Pydantic models?

See original GitHub issue

First 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:closed
  • Created 4 years ago
  • Reactions:8
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

13reactions
friborcommented, Jan 29, 2020

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:

class UserResource(BaseModel):
    id: int = Field(alias="identifier")
    name: str = Field(alias="fullname")

    class Config:
        allow_population_by_field_name = True

Here is the relevant part of the manual: Docs

3reactions
AIJIJIcommented, May 8, 2021

Even when I set allow_population_by_field_name = True. The response still return dict by alias. Example:

class RecordOut(BaseModel):
    id: str = Field(alias="_id")

    class Config:
        allow_population_by_field_name = True


@app.get("/record", response_model=RecordOut)
def read_record():
    record = {"_id": "123"}
    assert "id" in RecordOut(**record).dict(by_alias=False)
    return RecordOut(**record).dict(by_alias=False)
   # Response still has "_id" field!!!!

Am I doing something wrong?

OK, I find the solution: just add a param response_model_by_alias=False to the decorator.

Read more comments on GitHub >

github_iconTop Results From Across the Web

List of object attributes in pydantic model - Stack Overflow
As UserRole is a class, it is represented as an object (using a dictionary). If you want to represent it as a list...
Read more >
Models with Relationships in FastAPI - SQLModel
Models with Relationships¶ · Inheritance and Type Annotations¶ · Data Models Without Relationship Attributes¶ · Reference to Other Models¶.
Read more >
Many-To-Many Relationships In FastAPI - GormAnalysis
With the tweaks we made in step 2 above, we have the data we need in the correct objects to populate our pydantic...
Read more >
pydantic/Lobby - Gitter
Probably a dumb question. Does anyone know if there is an easy way to map all of a subclasses fields to a single...
Read more >
Better fields access and allowing a new character at the start ...
namedtuples, dataclasses, pydantic, django models, SQLAlchemy and many others suffer from a problem: How do you allow arbitrary field names ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found