[QUESTION] How to bridge Pydantic models with SQLAlchemy?
See original GitHub issueDescription
Up until database interaction is introduced, the tutorial for FastAPI uses pydantic models for everything, such as this example in the sextion on Extra Models :
class UserOut(BaseModel):
username: str
email: EmailStr
full_name: str = None
class UserInDB(BaseModel):
username: str
hashed_password: str
email: EmailStr
full_name: str = None
This alows for the “database model” to have private data which will not be exposed through the API. Later, in the section on security, a similar trick is used, but this time using inheritance to stack the two models (which I find makes the return-casting used by some functions better encoded in the type system).
class User(BaseModel):
username: str
email: str = None
full_name: str = None
disabled: bool = None
class UserInDB(User):
hashed_password: str
def get_db_user() -> UserInDB:
return UserInDB(
username="johndoe", full_name="John Doe",
email="johndoe@example.com",
hashed_password="fakehashedsecret",
disabled=False
)
def get_user() -> User:
return get_db_user()
However, when proper databases are introduced, those Pydantic models are dropped in favor of a single SQLAlchemy ORM model, with no effort to bridge the two parts. And while one could see this as the SQLAlchemy models completely superseding the Pydantic models, the fullstack demo app appears to actually use both, so there appears to be value in attempting to use them together, something which the documentation doesn’t seem to address.
So can/should Pydantic and SQLAlchemy models be used together? If they are, how is one meant to connect the two together and can this still be done while maintaining some kind of type hierarchy?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:81
- Comments:32 (20 by maintainers)
Top GitHub Comments
I just finished integrating Pydantic ORM mode into FastAPI, it is released as version
0.30.0
🎉The new docs include how to use Pydantic with SQLAlchemy, how relationships work, etc: https://fastapi.tiangolo.com/tutorial/sql-databases/
So, Pydantic and SQLAlchemy are separated. Pydantic is used for documentation, validation, and data serialization. SQLAlchemy for SQL ORM stuff.
FastAPI is not coupled with any DB, so, SQLAlchemy is optional.
If you don’t care about having documentation, validation, and serialization, you don’t need to use Pydantic, you could return SQLAlchemy models directly. They would be converted to JSON in a “best-effort” way.
If you want both, for now, you have to write both.
I agree I don’t like the duplication of properties in classes. But there’s still no way to automatically generate one from the other.
That’s a good candidate for a third-party package, that generates Pydantic models from SQLAlchemy models (or other ORMs) automatically. But it doesn’t exist yet. There are some attempts at doing something similar but I don’t know a complete solution yet. Hopefully, someone will build it (or I’ll do it later).
For now, I’ll take it as a request to update the docs clarifying the use of both Pydantic and SQLAlchemy at the same time.