sqlmodel
sqlmodel copied to clipboard
Is it possible to instantiate a SQLModel object with relationships from a `dict` type?
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the SQLModel documentation, with the integrated search.
- [X] I already searched in Google "How to X in SQLModel" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to SQLModel but to Pydantic.
- [X] I already checked if it is not related to SQLModel but to SQLAlchemy.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
from typing import List, Optional
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine
from pydantic import BaseModel
class Team(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
heroes: List["Hero"] = Relationship(back_populates="team")
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
team: Optional[Team] = Relationship(back_populates="heroes")
class Hero2(BaseModel):
id: int
team: Team
class Team2(BaseModel):
id: int
heroes: List["Hero2"]
# What I would like to be able to do
d = {"id": 123, "team": {"id": 124}} # fails
# d = {"id": 123, "team": Team(**{"id": 124})} # succeeds
h = Hero(**d)
print(h)
# The same idea but using vanilla Pydantic models
d2 = {"id": 123, "team": {"id": 124}}
h2 = Hero2(**d2)
print(h2)
Description
In Pydantic it is possible to instantiate objects directly from dicts (i.e. JSON) via ClassName(**dict). This also works for objects with nested objects (i.e. relationships in SQLModel). Is it possible to do the same in SQLModel? I would like to take a JSON like {"id": 123, "relationship_obj": {"id": 456, ...}} and have SQLModel correctly create the relationship model based on the type of the field & the key of the dict passed in.
The error received is:
File "/.../venv/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", lin
e 1729, in emit_backref_from_scalar_set_event
instance_state(child),
AttributeError: 'dict' object has no attribute '_sa_instance_state'
Operating System
Linux
Operating System Details
No response
SQLModel Version
0.0.6
Python Version
Python 3.9.5
Additional Context
No response
One thing I don't understand here is how FastAPI instantiates SQLModel objects from the JSON request object. I think there must be support for what I want to achieve, it's just not easily accessible or well documented.
Hm I thought it works, am using from_orm in our service too, but not sure if the relationships work in this - is discussed there, saying they would not work: https://github.com/tiangolo/sqlmodel/issues/224
I do have them in my return values.
I am noticing a similar issue, even doing Hero(team=Team(...)).team will give a Hero object has no attribute team.. Any way to fix this?
I just ran into this same issue. Drove me nuts trying to figure it out. I imagine many JSON posts to FastAPI have such nested statements so I'm surprised that this is an issue. I keep thinking I must be doing something wrong.
I think this is essentially a duplicate of this:
- #6
I agree that this is worthwhile, but I suggest closing this duplicate issue.