From b7b27966cf204045f91daae97b0ab13eeca6ae63 Mon Sep 17 00:00:00 2001 From: byrman Date: Sat, 8 Oct 2022 12:51:38 +0200 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=90=9B=20Fix=20SQLAlchemy=20version?= =?UTF-8?q?=201.4.36=20breaks=20SQLModel=20relationships=20(#315)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sqlmodel/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index d343c698e9..598b535b56 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -332,6 +332,7 @@ def __init__( # There's a SQLAlchemy relationship declared, that takes precedence # over anything else, use that and continue with the next attribute dict_used[rel_name] = rel_info.sa_relationship + setattr(cls, rel_name, rel_info.sa_relationship) # Fix #315 continue ann = cls.__annotations__[rel_name] temp_field = ModelField.infer( From 2f16326e2f8cbaa6a65ccc2f95667642abe3491d Mon Sep 17 00:00:00 2001 From: byrman Date: Sun, 9 Oct 2022 14:09:01 +0200 Subject: [PATCH 2/4] Test for sa_relationship. --- tests/test_main.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 22c62327da..452ad983b4 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,8 +1,9 @@ -from typing import Optional +from typing import List, Optional import pytest from sqlalchemy.exc import IntegrityError -from sqlmodel import Field, Session, SQLModel, create_engine +from sqlalchemy.orm import RelationshipProperty +from sqlmodel import Field, Relationship, Session, SQLModel, create_engine def test_should_allow_duplicate_row_if_unique_constraint_is_not_passed(clear_sqlmodel): @@ -91,3 +92,36 @@ class Hero(SQLModel, table=True): session.add(hero_2) session.commit() session.refresh(hero_2) + + +def test_sa_relationship(clear_sqlmodel): + """Test https://github.com/tiangolo/sqlmodel/issues/315#issuecomment-1272122306""" + + class Team(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + name: str = Field(unique=True) + heroes: List["Hero"] = Relationship( + sa_relationship=RelationshipProperty("Hero", back_populates="team") + ) + + class Hero(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + name: str = Field(unique=True) + team_id: Optional[int] = Field(default=None, foreign_key="team.id") + team: Optional[Team] = Relationship( + sa_relationship=RelationshipProperty("Team", back_populates="heroes") + ) + + team_preventers = Team(name="Preventers") + hero_rusty_man = Hero(name="Rusty-Man", team=team_preventers) + + engine = create_engine("sqlite://", echo=True) + + SQLModel.metadata.create_all(engine) + + with Session(engine) as session: + session.add(hero_rusty_man) + session.commit() + session.refresh(hero_rusty_man) + # The next statement should not raise an AttributeError + assert hero_rusty_man.team.name == "Preventers" From 2d6e7a190493cdc7f701ca4e93cfdf3741db584b Mon Sep 17 00:00:00 2001 From: byrman Date: Sun, 9 Oct 2022 14:25:35 +0200 Subject: [PATCH 3/4] Ignore flake8 warning. --- tests/test_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_main.py b/tests/test_main.py index 452ad983b4..51ecdf79f4 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -100,7 +100,7 @@ def test_sa_relationship(clear_sqlmodel): class Team(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str = Field(unique=True) - heroes: List["Hero"] = Relationship( + heroes: List["Hero"] = Relationship( # noqa: F821 sa_relationship=RelationshipProperty("Hero", back_populates="team") ) From 512482c7c7a3859c2bec70ddcbfb1d81de29659d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 22 Oct 2023 15:56:25 +0400 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=85=20Tweak=20test=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_main.py b/tests/test_main.py index 51ecdf79f4..72465cda33 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -94,7 +94,7 @@ class Hero(SQLModel, table=True): session.refresh(hero_2) -def test_sa_relationship(clear_sqlmodel): +def test_sa_relationship_property(clear_sqlmodel): """Test https://github.com/tiangolo/sqlmodel/issues/315#issuecomment-1272122306""" class Team(SQLModel, table=True): @@ -124,4 +124,5 @@ class Hero(SQLModel, table=True): session.commit() session.refresh(hero_rusty_man) # The next statement should not raise an AttributeError + assert hero_rusty_man.team assert hero_rusty_man.team.name == "Preventers"