22
33from sqlalchemy import ForeignKey
44from sqlalchemy .orm import mapped_column
5- from sqlmodel import Field , Session , SQLModel , create_engine , select
5+ from sqlmodel import Field , Relationship , Session , SQLModel , create_engine , select
66
77from tests .conftest import needs_pydanticv2
88
@@ -16,7 +16,7 @@ class Hero(SQLModel, table=True):
1616
1717 __mapper_args__ = {
1818 "polymorphic_on" : "hero_type" ,
19- "polymorphic_identity" : "hero " ,
19+ "polymorphic_identity" : "normal_hero " ,
2020 }
2121
2222 class DarkHero (Hero ):
@@ -59,7 +59,7 @@ class Hero(SQLModel, table=True):
5959
6060 __mapper_args__ = {
6161 "polymorphic_on" : "hero_type" ,
62- "polymorphic_identity" : "hero " ,
62+ "polymorphic_identity" : "normal_hero " ,
6363 }
6464
6565 class DarkHero (Hero ):
@@ -103,7 +103,7 @@ class Hero(SQLModel, table=True):
103103
104104 __mapper_args__ = {
105105 "polymorphic_on" : "hero_type" ,
106- "polymorphic_identity" : "hero " ,
106+ "polymorphic_identity" : "normal_hero " ,
107107 }
108108
109109 class DarkHero (Hero ):
@@ -130,3 +130,48 @@ class DarkHero(Hero):
130130 result = db .exec (statement ).all ()
131131 assert len (result ) == 1
132132 assert isinstance (result [0 ].dark_power , str )
133+
134+
135+ @needs_pydanticv2
136+ def test_polymorphic_relationship (clear_sqlmodel ) -> None :
137+ class Tool (SQLModel , table = True ):
138+ __tablename__ = "tool_table"
139+
140+ id : int = Field (primary_key = True )
141+
142+ name : str
143+
144+ class Person (SQLModel , table = True ):
145+ __tablename__ = "person_table"
146+
147+ id : int = Field (primary_key = True )
148+
149+ discriminator : str
150+ name : str
151+
152+ tool_id : int = Field (foreign_key = "tool_table.id" )
153+ tool : Tool = Relationship ()
154+
155+ __mapper_args__ = {
156+ "polymorphic_on" : "discriminator" ,
157+ "polymorphic_identity" : "simple_person" ,
158+ }
159+
160+ class Worker (Person ):
161+ __mapper_args__ = {
162+ "polymorphic_identity" : "worker" ,
163+ }
164+
165+ engine = create_engine ("sqlite:///:memory:" , echo = True )
166+ SQLModel .metadata .create_all (engine )
167+ with Session (engine ) as db :
168+ tool = Tool (id = 1 , name = "Hammer" )
169+ db .add (tool )
170+ worker = Worker (id = 2 , name = "Bob" , tool_id = 1 )
171+ db .add (worker )
172+ db .commit ()
173+
174+ statement = select (Worker ).where (Worker .tool_id == 1 )
175+ result = db .exec (statement ).all ()
176+ assert len (result ) == 1
177+ assert isinstance (result [0 ].tool , Tool )
0 commit comments