With Relationship field filled but empty foreign_key validate raise ValidationError #785
Answered
by
YuriiMotov
mlachowski
asked this question in
Questions
-
First Check
Commit to Help
Example Codefrom typing import Optional, List
from sqlmodel import Field, Session, SQLModel, create_engine, select, Relationship
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
children: List["Child"] = Relationship(back_populates="hero")
class Child(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
hero_id: int = Field(foreign_key="hero.id")
hero: Hero = Relationship(back_populates="children")
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True)
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
def create_heroes():
hero_1 = Hero(name="Deadpond")
with Session(engine) as session:
session.add(hero_1)
session.commit()
def select_hero():
with Session(engine) as session:
statement = select(Hero)
results = session.exec(statement)
return results.first()
def main():
create_db_and_tables()
create_heroes()
hero = select_hero()
Child.model_validate({"name": "Deadpond child", "hero": hero})
if __name__ == "__main__":
main() Description
What is the best approach for this? Should I always populate the Operating SystemWindows Operating System DetailsNo response SQLModel Version0.0.14 Python VersionPython 3.11.7 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Answered by
YuriiMotov
Aug 21, 2025
Replies: 1 comment
-
You shouldn't use models with Instead you should create new class ChildBase(SQLModel):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
class Child(ChildBase, table=True):
hero_id: int = Field(foreign_key="hero.id")
hero: Hero = Relationship(back_populates="children")
class ChildPublic(ChildBase):
hero: HeroPublic Runnable code example in the details: from typing import Optional, List
from sqlmodel import Field, Session, SQLModel, create_engine, select, Relationship
class HeroBase(SQLModel):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
class Hero(HeroBase, table=True):
children: List["Child"] = Relationship(back_populates="hero")
class HeroPublic(HeroBase):
pass
class ChildBase(SQLModel):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
class Child(ChildBase, table=True):
hero_id: int = Field(foreign_key="hero.id")
hero: Hero = Relationship(back_populates="children")
class ChildPublic(ChildBase):
hero: HeroPublic
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True)
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
def create_heroes():
hero_1 = Hero(name="Deadpond")
with Session(engine) as session:
session.add(hero_1)
session.commit()
def select_hero():
with Session(engine) as session:
statement = select(Hero)
results = session.exec(statement)
return results.first()
def main():
create_db_and_tables()
create_heroes()
hero = select_hero()
print(ChildPublic.model_validate({"name": "Deadpond child", "hero": hero}))
if __name__ == "__main__":
main() |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
YuriiMotov
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You shouldn't use models with
table=True
for validation. Such models bypass some validation and relationships are not validated.Instead you should create new
ChildPublic
model and use it for validation\serialization:Runnable code example in the details: