diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2021-05-21 15:18:15 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2021-05-21 15:18:15 +0000 |
| commit | b2ab2bbf4faf508b3fa5749969019203a702786f (patch) | |
| tree | 8acf963f97007aada72fc6219273874f30dd7b82 | |
| parent | 52f4d384b6236d00c07afa66ffb8ae2343a87b0f (diff) | |
| parent | e26487e234e4192db7e75cedf029df6de83f3415 (diff) | |
| download | sqlalchemy-b2ab2bbf4faf508b3fa5749969019203a702786f.tar.gz | |
Merge "Detect back_populates referring to non-relationship"
| -rw-r--r-- | lib/sqlalchemy/orm/relationships.py | 7 | ||||
| -rw-r--r-- | test/orm/test_relationships.py | 34 |
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index 5d87ef797..00a14b04c 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -2046,6 +2046,13 @@ class RelationshipProperty(StrategizedProperty): def _add_reverse_property(self, key): other = self.mapper.get_property(key, _configure_mappers=False) + if not isinstance(other, RelationshipProperty): + raise sa_exc.InvalidRequestError( + "back_populates on relationship '%s' refers to attribute '%s' " + "that is not a relationship. The back_populates parameter " + "should refer to the name of a relationship on the target " + "class." % (self, other) + ) # viewonly and sync_backref cases # 1. self.viewonly==True and other.sync_backref==True -> error # 2. self.viewonly==True and other.viewonly==False and diff --git a/test/orm/test_relationships.py b/test/orm/test_relationships.py index 867994866..77a218beb 100644 --- a/test/orm/test_relationships.py +++ b/test/orm/test_relationships.py @@ -2304,6 +2304,39 @@ class ManualBackrefTest(_fixtures.FixtureTest): configure_mappers, ) + def test_back_propagates_not_relationship(self): + addr, Addr, users, User = ( + self.tables.addresses, + self.classes.Address, + self.tables.users, + self.classes.User, + ) + + mapper( + User, + users, + properties={ + "addresses": relationship(Addr, back_populates="user_id") + }, + ) + + mapper( + Addr, + addr, + properties={ + "users": relationship(User, back_populates="addresses") + }, + ) + + assert_raises_message( + sa.exc.InvalidRequestError, + "back_populates on relationship 'User.addresses' refers to " + "attribute 'Address.user_id' that is not a relationship. " + "The back_populates parameter should refer to the name of " + "a relationship on the target class.", + configure_mappers, + ) + class NoLoadBackPopulates(_fixtures.FixtureTest): @@ -3146,6 +3179,7 @@ class ViewOnlySyncBackref(fixtures.MappedTest): return str(self.__dict__) cases = { + # (B_a_view, B_a_sync, A_bs_view, A_bs_sync) (0, 0, 0, 0): Case(), (0, 0, 0, 1): Case(Abs_evt=1), (0, 0, 1, 0): Case(), |
