--- /dev/null
+.. change::
+ :tags: bug, orm
+ :tickets: 4954
+
+ The :paramref:`.relationship.omit_join` flag was not intended to be
+ manually set to True, and will now emit a warning when this occurs. The
+ omit_join optimization is detected automatically, and the ``omit_join``
+ flag was only intended to disable the optimization in the hypothetical case
+ that the optimization may have interfered with correct results, which has
+ not been observed with the modern version of this feature. Setting the
+ flag to True when it is not automatically detected may cause the selectin
+ load feature to not work correctly when a non-default primary join
+ condition is in use.
+
:param omit_join:
Allows manual control over the "selectin" automatic join
optimization. Set to ``False`` to disable the "omit join" feature
- added in SQLAlchemy 1.3.
+ added in SQLAlchemy 1.3; or leave as ``None`` to leave automatic
+ optimization in place.
+
+ .. note:: This flag may only be set to ``False``. It is not
+ necessary to set it to ``True`` as the "omit_join" optimization is
+ automatically detected; if it is not detected, then the
+ optimization is not supported.
+
+ .. versionchanged:: 1.3.11 setting ``omit_join`` to True will now
+ emit a warning as this was not the intended use of this flag.
.. versionadded:: 1.3
self.doc = doc
self.active_history = active_history
self.join_depth = join_depth
+ if omit_join:
+ util.warn(
+ "setting omit_join to True is not supported; selectin "
+ "loading of this relationship may not work correctly if this "
+ "flag is set explicitly. omit_join optimization is "
+ "automatically detected for conditions under which it is "
+ "supported."
+ )
+
self.omit_join = omit_join
self.local_remote_pairs = _local_remote_pairs
self.bake_queries = bake_queries
id = Column(Integer, primary_key=True)
b_id = Column(ForeignKey("b.id"))
b = relationship("B")
+ b_no_omit_join = relationship("B", omit_join=False)
q = Column(Integer)
class B(fixtures.ComparableEntity, Base):
)
s.commit()
+ def test_omit_join_warn_on_true(self):
+ with testing.expect_warnings(
+ "setting omit_join to True is not supported; selectin "
+ "loading of this relationship"
+ ):
+ relationship("B", omit_join=True)
+
def test_use_join_parent_criteria(self):
A, B = self.classes("A", "B")
s = Session()
],
)
+ def test_use_join_omit_join_false(self):
+ A, B = self.classes("A", "B")
+ s = Session()
+ q = s.query(A).options(selectinload(A.b_no_omit_join)).order_by(A.id)
+ results = self.assert_sql_execution(
+ testing.db,
+ q.all,
+ CompiledSQL(
+ "SELECT a.id AS a_id, a.b_id AS a_b_id, a.q AS a_q "
+ "FROM a ORDER BY a.id",
+ [{}],
+ ),
+ CompiledSQL(
+ "SELECT a_1.id AS a_1_id, b.id AS b_id, b.x AS b_x, "
+ "b.y AS b_y FROM a AS a_1 JOIN b ON b.id = a_1.b_id "
+ "WHERE a_1.id IN ([POSTCOMPILE_primary_keys]) ORDER BY a_1.id",
+ [{"primary_keys": [1, 2, 3, 4, 5]}],
+ ),
+ )
+
+ b1, b2 = B(id=1, x=5, y=9), B(id=2, x=10, y=8)
+ eq_(
+ results,
+ [
+ A(id=1, b_no_omit_join=b1),
+ A(id=2, b_no_omit_join=b2),
+ A(id=3, b_no_omit_join=b2),
+ A(id=4, b_no_omit_join=None),
+ A(id=5, b_no_omit_join=b1),
+ ],
+ )
+
def test_use_join_parent_degrade_on_defer(self):
A, B = self.classes("A", "B")
s = Session()