Skip to content

Commit d5219aa

Browse files
byrmantiangolo
andauthored
🐛 Fix SQLAlchemy version 1.4.36 breaks SQLModel relationships (#315) (#461)
Co-authored-by: Sebastián Ramírez <[email protected]>
1 parent aa7169b commit d5219aa

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

sqlmodel/main.py

+1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ def __init__(
333333
# There's a SQLAlchemy relationship declared, that takes precedence
334334
# over anything else, use that and continue with the next attribute
335335
dict_used[rel_name] = rel_info.sa_relationship
336+
setattr(cls, rel_name, rel_info.sa_relationship) # Fix #315
336337
continue
337338
ann = cls.__annotations__[rel_name]
338339
temp_field = ModelField.infer(

tests/test_main.py

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
from typing import Optional
1+
from typing import List, Optional
22

33
import pytest
44
from sqlalchemy.exc import IntegrityError
5-
from sqlmodel import Field, Session, SQLModel, create_engine
5+
from sqlalchemy.orm import RelationshipProperty
6+
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine
67

78

89
def test_should_allow_duplicate_row_if_unique_constraint_is_not_passed(clear_sqlmodel):
@@ -91,3 +92,37 @@ class Hero(SQLModel, table=True):
9192
session.add(hero_2)
9293
session.commit()
9394
session.refresh(hero_2)
95+
96+
97+
def test_sa_relationship_property(clear_sqlmodel):
98+
"""Test https://github.com/tiangolo/sqlmodel/issues/315#issuecomment-1272122306"""
99+
100+
class Team(SQLModel, table=True):
101+
id: Optional[int] = Field(default=None, primary_key=True)
102+
name: str = Field(unique=True)
103+
heroes: List["Hero"] = Relationship( # noqa: F821
104+
sa_relationship=RelationshipProperty("Hero", back_populates="team")
105+
)
106+
107+
class Hero(SQLModel, table=True):
108+
id: Optional[int] = Field(default=None, primary_key=True)
109+
name: str = Field(unique=True)
110+
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
111+
team: Optional[Team] = Relationship(
112+
sa_relationship=RelationshipProperty("Team", back_populates="heroes")
113+
)
114+
115+
team_preventers = Team(name="Preventers")
116+
hero_rusty_man = Hero(name="Rusty-Man", team=team_preventers)
117+
118+
engine = create_engine("sqlite://", echo=True)
119+
120+
SQLModel.metadata.create_all(engine)
121+
122+
with Session(engine) as session:
123+
session.add(hero_rusty_man)
124+
session.commit()
125+
session.refresh(hero_rusty_man)
126+
# The next statement should not raise an AttributeError
127+
assert hero_rusty_man.team
128+
assert hero_rusty_man.team.name == "Preventers"

0 commit comments

Comments
 (0)