--- /dev/null
+.. change::
+ :tags: bug, orm
+ :tickets: 5269
+
+ An informative error message is raised when an ORM many-to-one comparison
+ is attempted against an object that is not an actual mapped instance.
+ Comparisons such as those to scalar subqueries aren't supported;
+ generalized comparison with subqueries is better achieved using
+ :meth:`~.RelationshipProperty.Comparator.has`.
+
alias_secondary=True,
):
if state is not None:
- state = attributes.instance_state(state)
+ try:
+ state = inspect(state)
+ except sa_exc.NoInspectionAvailable:
+ state = None
+ if state is None or not getattr(state, "is_instance", False):
+ raise sa_exc.ArgumentError(
+ "Mapped instance expected for relationship "
+ "comparison to object. Classes, queries and other "
+ "SQL elements are not accepted in this context; for "
+ "comparison with a subquery, "
+ "use %s.has(**criteria)." % self
+ )
reverse_direction = not value_is_parent
if state is None:
[Order(id=3)],
)
- def test_comparison(self):
+ @testing.combinations(
+ lambda sess, User, Address: (
+ sess.query(Address).filter(
+ Address.user == sess.query(User).as_scalar()
+ )
+ ),
+ lambda sess, User, Address: (
+ sess.query(Address).filter_by(user=sess.query(User).as_scalar())
+ ),
+ lambda sess, User, Address: (
+ sess.query(Address).filter(Address.user == sess.query(User))
+ ),
+ lambda sess, User, Address: (
+ sess.query(Address).filter(
+ Address.user == sess.query(User).subquery()
+ )
+ ),
+ lambda sess, User, Address: (
+ sess.query(Address).filter_by(user="foo")
+ ),
+ )
+ def test_object_comparison_needs_object(self, fn):
+ User, Address = (
+ self.classes.User,
+ self.classes.Address,
+ )
+
+ sess = create_session()
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ "Mapped instance expected for relationship comparison to object.",
+ fn,
+ sess,
+ User,
+ Address,
+ ),
+
+ def test_object_comparison(self):
"""test scalar comparison to an object instance"""
Item, Order, Dingaling, User, Address = (