In models, have a User
that can have many roles and Role
that can have many users (many-to-many):
class UsersRoles(SQLModel, table=True):
user_id: int = Field(foreign_key='users.id', primary_key=True)
role_id: int = Field(foreign_key='roles.id', primary_key=True)
class User(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str
email: str = Field(unique=True, index=True)
roles: list['Role'] = Relationship(back_populates='users', link_model=UsersRoles)
class Role(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str = Field(unique=True)
users: list['User'] = Relationship(back_populates='roles', link_model=UsersRoles)
In the api, declare the endpoint:
@router.post('/user')
def create_user(user: User) -> User:
with get_session() as session:
session.add(user)
session.commit()
session.refresh(user)
return user
Then I want to create the User
with roles and call the endpoint:
role = Role(name='admin')
user = User(name='Jane', email='test@xyz.com', roles=[role])
# payload = {
# 'name': 'Jane',
# 'email': 'test@xyz.com',
# 'roles': ['admin']
# }
payload = user.json()
response = requests.post('http://localhost:8000/user', json=payload)
Error: Get what looks like a SqlAlchemy error:
state = <sqlalchemy.orm.state.InstanceState object at 0x0000016B1F3B6BF0>
child = {'name': 'user'}
initiator = <sqlalchemy.orm.attributes.AttributeEvent object at 0x0000016B1F2FF780>
def emit_backref_from_collection_append_event(state, child, initiator):
if child is None:
return
> child_state, child_dict = instance_state(child), instance_dict(child)
E AttributeError: 'dict' object has no attribute '_sa_instance_state'
How can I make this work?
- The same thing happens whether the
role
already exists in the DB or not. - Works if the payload (
user
) doesn't haveroles
in it. - The error comes up before the controller code gets executed, ie, in api doesn't even reach the first line inside
create_user(...)
.