diff options
| -rw-r--r-- | CHANGES | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 15 | ||||
| -rw-r--r-- | test/orm/test_query.py | 17 |
3 files changed, 34 insertions, 3 deletions
@@ -6,6 +6,11 @@ CHANGES 0.6.2 ===== - orm + - Query.join() will check for a call of the + form query.join(target, clause_expression), + i.e. missing the tuple, and raise an informative + error message that this is the wrong calling form. + - Fixed bug regarding flushes on self-referential bi-directional many-to-many relationships, where two objects made to mutually reference each other diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 6b36b370a..b3588ae59 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1110,7 +1110,15 @@ class Query(object): if not from_joinpoint: self._reset_joinpoint() - + + if len(keys) >= 2 and \ + isinstance(keys[1], expression.ClauseElement) and \ + not isinstance(keys[1], expression.FromClause): + raise sa_exc.ArgumentError( + "You appear to be passing a clause expression as the second " + "argument to query.join(). Did you mean to use the form " + "query.join((target, onclause))? Note the tuple.") + for arg1 in util.to_list(keys): if isinstance(arg1, tuple): arg1, arg2 = arg1 @@ -1326,9 +1334,10 @@ class Query(object): if clause is None: raise sa_exc.InvalidRequestError( "Could not find a FROM clause to join from") - + clause = orm_join(clause, right, onclause, - isouter=outerjoin, join_to_left=join_to_left) + isouter=outerjoin, join_to_left=join_to_left) + self._from_obj = self._from_obj + (clause,) def _reset_joinpoint(self): diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 4372ee840..e8289e08c 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -1725,6 +1725,23 @@ class JoinTest(QueryTest, AssertsCompiledSQL): "ON addresses.id = orders.address_id" , use_default_dialect=True ) + + def test_common_mistake(self): + sess = create_session() + + subq = sess.query(User).subquery() + assert_raises_message( + sa_exc.ArgumentError, "You appear to be passing a clause expression", + sess.query(User).join, subq, User.name==subq.c.name) + + subq = sess.query(Order).subquery() + assert_raises_message( + sa_exc.ArgumentError, "You appear to be passing a clause expression", + sess.query(User).join, subq, User.id==subq.c.user_id) + + assert_raises_message( + sa_exc.ArgumentError, "You appear to be passing a clause expression", + sess.query(User).join, Order, User.id==Order.user_id) def test_single_prop(self): sess = create_session() |
