From: Mike Bayer Date: Tue, 19 Jul 2016 16:36:21 +0000 (-0400) Subject: Remove same-named relationship warning X-Git-Tag: rel_1_1_0b3~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8952a30f0a27d6b57e7b054b8b464382b67e3828;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Remove same-named relationship warning Removed a warning that dates back to 0.4 which emits when a same-named relationship is placed on two mappers that inherits via joined or single table inheritance. The warning does not apply to the current unit of work implementation. Change-Id: If528ec3a2f4dc60712d9044fd1ec6c4dfbf0eadb Fixes: #3749 --- diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index 593cbb3caf..9821199827 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -21,6 +21,20 @@ .. changelog:: :version: 1.1.0b3 + .. change:: + :tags: change, orm + :tickets: 3749 + + Removed a warning that dates back to 0.4 which emits when a same-named + relationship is placed on two mappers that inherits via joined or + single table inheritance. The warning does not apply to the + current unit of work implementation. + + .. seealso:: + + :ref:`change_3749` + + .. change:: :tags: bug, sql :tickets: 3745 diff --git a/doc/build/changelog/migration_11.rst b/doc/build/changelog/migration_11.rst index d0f73b7267..36c5ead3c2 100644 --- a/doc/build/changelog/migration_11.rst +++ b/doc/build/changelog/migration_11.rst @@ -588,6 +588,47 @@ for an attribute being replaced. :ticket:`3630` +.. _change_3749: + +Same-named relationships on inheriting mappers no longer warn +-------------------------------------------------------------- + +When creating two mappers in an inheritance scenario, placing a relationship +on both with the same name would emit the warning +"relationship '' on mapper supersedes the same relationship +on inherited mapper ''; this can cause dependency issues during flush". +An example is as follows:: + + class A(Base): + __tablename__ = 'a' + id = Column(Integer, primary_key=True) + bs = relationship("B") + + + class ASub(A): + __tablename__ = 'a_sub' + id = Column(Integer, ForeignKey('a.id'), primary_key=True) + bs = relationship("B") + + + class B(Base): + __tablename__ = 'b' + id = Column(Integer, primary_key=True) + a_id = Column(ForeignKey('a.id')) + + +This warning dates back to the 0.4 series in 2007 and is based on a version of +the unit of work code that has since been entirely rewritten. Currently, there +is no known issue with the same-named relationships being placed on a base +class and a descendant class, so the warning is lifted. However, note that +this use case is likely not prevalent in real world use due to the warning. +While rudimentary test support is added for this use case, it is possible that +some new issue with this pattern may be identified. + +.. versionadded:: 1.1.0b3 + +:ticket:`3749` + .. _change_3653: Hybrid properties and methods now propagate the docstring as well as .info diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index 4d5e5d29db..e8a2992b06 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -1742,17 +1742,6 @@ class RelationshipProperty(StrategizedProperty): (self.key, self.parent.class_.__name__, self.parent.class_.__name__)) - # check for conflicting relationship() on superclass - if not self.parent.concrete: - for inheriting in self.parent.iterate_to_root(): - if inheriting is not self.parent \ - and inheriting.has_property(self.key): - util.warn("Warning: relationship '%s' on mapper " - "'%s' supersedes the same relationship " - "on inherited mapper '%s'; this can " - "cause dependency issues during flush" - % (self.key, self.parent, inheriting)) - def _get_cascade(self): """Return the current cascade setting for this :class:`.RelationshipProperty`. diff --git a/test/orm/inheritance/test_relationship.py b/test/orm/inheritance/test_relationship.py index 379d8f7e46..0bbb138b04 100644 --- a/test/orm/inheritance/test_relationship.py +++ b/test/orm/inheritance/test_relationship.py @@ -1856,4 +1856,73 @@ class MultipleAdaptUsesEntityOverTableTest(AssertsCompiledSQL, fixtures.MappedTe "(a AS a_1 JOIN c AS c_1 ON a_1.id = c_1.id) ON c_1.bid = b.id " "JOIN (a AS a_2 JOIN d AS d_1 ON a_2.id = d_1.id) " "ON d_1.cid = c_1.id" - ) \ No newline at end of file + ) + + +class SameNameOnJoined(fixtures.MappedTest): + + run_setup_mappers = 'once' + run_inserts = None + run_deletes = None + + @classmethod + def define_tables(cls, metadata): + Table( + 'a', metadata, + Column( + 'id', Integer, primary_key=True, + test_needs_autoincrement=True) + ) + Table( + 'a_sub', metadata, + Column('id', Integer, ForeignKey('a.id'), primary_key=True) + ) + Table( + 'b', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('a_id', Integer, ForeignKey('a.id')) + + ) + + @classmethod + def setup_mappers(cls): + class A(cls.Comparable): + pass + + class ASub(A): + pass + + class B(cls.Comparable): + pass + + mapper(A, cls.tables.a, properties={ + 'bs': relationship(B, cascade="all, delete-orphan") + }) + + mapper(ASub, cls.tables.a_sub, inherits=A, properties={ + 'bs': relationship(B, cascade="all, delete-orphan") + }) + + mapper(B, cls.tables.b) + + def test_persist(self): + A, ASub, B = self.classes('A', 'ASub', 'B') + + s = Session(testing.db) + + s.add_all([ + A(bs=[B(), B(), B()]), + ASub(bs=[B(), B(), B()]) + ]) + s.commit() + + eq_(s.query(B).count(), 6) + + for a in s.query(A): + eq_(len(a.bs), 3) + s.delete(a) + + s.commit() + + eq_(s.query(B).count(), 0)