:ref:`error_bbf0`
+.. _error_qzyx:
+
+relationship X will copy column Q to column P, which conflicts with relationship(s): 'Y'
+----------------------------------------------------------------------------------------
+
+This warning refers to the case when two or more relationships will write data to the
+same columns on flush, but the ORM does not have any kind of back population configuration
+between the two relationships. The fix is usually to install the correct
+:paramref:`_orm.back_populates` configuration. Given the following mapping::
+
+ class Parent(Base):
+ __tablename__ = "parent"
+ id = Column(Integer, primary_key=True)
+ children = relationship("Child")
+
+
+ class Child(Base):
+ __tablename__ = "child"
+ id = Column(Integer, primary_key=True)
+ parent_id = Column(ForeignKey("parent.id"))
+ parent = relationship("Parent")
+
+The above mapping will generate warnings::
+
+ SAWarning: relationship 'Child.parent' will copy column parent.id to column child.parent_id,
+ which conflicts with relationship(s): 'Parent.children' (copies parent.id to child.parent_id).
+
+The relationships ``Child.parent`` and ``Parent.children`` appear to be in conflict.
+The solution is to apply :paramref:`_orm.relationship.back_populates`::
+
+ class Parent(Base):
+ __tablename__ = "parent"
+ id = Column(Integer, primary_key=True)
+ children = relationship("Child", back_populates="parent")
+
+
+ class Child(Base):
+ __tablename__ = "child"
+ id = Column(Integer, primary_key=True)
+ parent_id = Column(ForeignKey("parent.id"))
+ parent = relationship("Parent", back_populates="children")
+
+For more customized relationships where an "overlap" situation may be
+intentional and cannot be resolved, the :paramref:`_orm.relationship.overlaps`
+parameter may specify the names of relationships for which the warning should
+not take effect. This typically occurs for two or more relationships to the
+same underlying table that include custom
+:paramref:`_orm.relationship.primaryjoin` conditions that limit the related
+items in each case::
+
+ class Parent(Base):
+ __tablename__ = "parent"
+ id = Column(Integer, primary_key=True)
+ c1 = relationship(
+ "Child",
+ primaryjoin="and_(Parent.id == Child.parent_id, Child.flag == 0)",
+ backref="parent",
+ overlaps="c2, parent"
+ )
+ c2 = relationship(
+ "Child",
+ primaryjoin="and_(Parent.id == Child.parent_id, Child.flag == 1)",
+ overlaps="c1, parent"
+ )
+
+
+ class Child(Base):
+ __tablename__ = "child"
+ id = Column(Integer, primary_key=True)
+ parent_id = Column(ForeignKey("parent.id"))
+
+ flag = Column(Integer)
+
+
+Above, the ORM will know that the overlap between ``Parent.c1``,
+``Parent.c2`` and ``Child.parent`` is intentional.
+
AsyncIO Exceptions
==================
.. versionadded:: 1.4
+ .. seealso::
+
+ :ref:`error_qzyx` - usage example
+
:param bake_queries=True:
Use the :class:`.BakedQuery` cache to cache the construction of SQL
used in lazy loads. True by default. Set to False if the
and self.prop.key not in pr._overlaps
and not self.prop.parent.is_sibling(pr.parent)
and not self.prop.mapper.is_sibling(pr.mapper)
+ and not self.prop.parent.is_sibling(pr.mapper)
+ and not self.prop.mapper.is_sibling(pr.parent)
and (
self.prop.key != pr.key
or not self.prop.parent.common_parent(pr.parent)
"'%s' (copies %s to %s)" % (pr, fr_, to_)
for (pr, fr_) in other_props
),
- )
+ ),
+ code="qzyx",
)
self._track_overlapping_sync_targets[to_][self.prop] = from_
configure_mappers()
+ def _fixture_four(self):
+ Base = declarative_base(metadata=self.metadata)
+
+ class A(Base):
+ __tablename__ = "a"
+
+ id = Column(Integer, primary_key=True)
+
+ c_id = Column(ForeignKey("c.id"))
+
+ class B1(A):
+ pass
+
+ class B2(A):
+ pass
+
+ class C(Base):
+ __tablename__ = "c"
+
+ id = Column(Integer, primary_key=True)
+ b1 = relationship(B1, backref="c")
+ b2 = relationship(B2, backref="c")
+
@testing.provide_metadata
def _test_fixture_one_run(self, **kw):
A, AMember, B, BSub1, BSub2 = self._fixture_one(**kw)
setup_backrefs=False,
)
+ @testing.provide_metadata
+ def test_fixture_four(self):
+ self._fixture_four()
+
@testing.provide_metadata
def test_simple_backrefs_works(self):
self._fixture_two(setup_backrefs=True)