Mike Bayer  committed 7097a34

- removed info about _local_remote_pairs from PropertyLoader.__determine_fks
- added order_by(), group_by(), having() to the list of "no offset()/limit()", [ticket:851]

  • Participants
  • Parent commits 83ceaf7

Comments (0)

Files changed (4)

File lib/sqlalchemy/orm/

                     if arg_foreign_keys:
                         raise sa_exc.ArgumentError("Could not determine relation direction for primaryjoin condition '%s', on relation %s. "
-                            "Specify _local_remote_pairs=[(local, remote), (local, remote), ...] to explicitly establish the local/remote column pairs." % (self.primaryjoin, self))
+                            "Are the columns in foreign_keys present within the given join condition ?" % (self.primaryjoin, self))
                         raise sa_exc.ArgumentError("Could not determine relation direction for primaryjoin condition '%s', on relation %s. "
                             "Specify the foreign_keys argument to indicate which columns on the relation are foreign." % (self.primaryjoin, self))

File lib/sqlalchemy/orm/

         if self._limit is not None or self._offset is not None:
             # TODO: do we want from_self() to be implicit here ?  i vote explicit for the time being
             raise sa_exc.InvalidRequestError("Query.%s() being called on a Query which already has LIMIT or OFFSET applied. "
-            "To filter/join to the row-limited results of the query, call from_self() first."
+            "To modify the row-limited results of a Query, call from_self() first.  Otherwise, call %s() before limit() or offset() are applied." % (meth, meth)
     def __no_criterion(self):
             self._order_by = self._order_by + criterion
     order_by = util.array_as_starargs_decorator(order_by)
-    order_by = _generative(__no_statement_condition)(order_by)
+    order_by = _generative(__no_statement_condition, __no_limit_offset)(order_by)
     def group_by(self, *criterion):
         """apply one or more GROUP BY criterion to the query and return the newly resulting ``Query``"""
             self._group_by = self._group_by + criterion
     group_by = util.array_as_starargs_decorator(group_by)
-    group_by = _generative(__no_statement_condition)(group_by)
+    group_by = _generative(__no_statement_condition, __no_limit_offset)(group_by)
     def having(self, criterion):
         """apply a HAVING criterion to the query and return the newly resulting ``Query``."""
             self._having = self._having & criterion
             self._having = criterion
-    having = _generative(__no_statement_condition)(having)
+    having = _generative(__no_statement_condition, __no_limit_offset)(having)
     def join(self, *props, **kwargs):
         """Create a join against this ``Query`` object's criterion

File test/orm/

             l = q.limit(2).all()
             assert self.static.user_all_result[:2] == l
-            l = q.limit(2).offset(1).order_by(
+            l = q.order_by(
             print self.static.user_all_result[1:3]
             print l
             assert self.static.user_all_result[1:3] == l

File test/orm/

     def test_no_limit_offset(self):
         s = create_session()
-        q = s.query(User).limit(2)
-        self.assertRaises(sa_exc.InvalidRequestError, q.join, "addresses")
+        for q in (
+            s.query(User).limit(2),
+            s.query(User).offset(2),
+            s.query(User).limit(2).offset(2)
+        ):
+            self.assertRaises(sa_exc.InvalidRequestError, q.join, "addresses")
-        self.assertRaises(sa_exc.InvalidRequestError, q.filter,'ed')
+            self.assertRaises(sa_exc.InvalidRequestError, q.filter,'ed')
-        self.assertRaises(sa_exc.InvalidRequestError, q.filter_by, name='ed')
+            self.assertRaises(sa_exc.InvalidRequestError, q.filter_by, name='ed')
+            self.assertRaises(sa_exc.InvalidRequestError, q.order_by, 'foo')
+            self.assertRaises(sa_exc.InvalidRequestError, q.group_by, 'foo')
+            self.assertRaises(sa_exc.InvalidRequestError, q.having, 'foo')
     def test_no_from(self):
         s = create_session()
         oalias = aliased(Order)
         for q in [
-            sess.query(Order, oalias).filter(Order.user_id==oalias.user_id).filter(Order.user_id==7).filter(>,
-            sess.query(Order, oalias)._from_self().filter(Order.user_id==oalias.user_id).filter(Order.user_id==7).filter(>,
+            sess.query(Order, oalias).filter(Order.user_id==oalias.user_id).filter(Order.user_id==7).filter(>,,
+            sess.query(Order, oalias)._from_self().filter(Order.user_id==oalias.user_id).filter(Order.user_id==7).filter(>,,
             # here we go....two layers of aliasing
             sess.query(Order, oalias).filter(Order.user_id==oalias.user_id).filter(Order.user_id==7).filter(>,,
-            q.order_by(,,
+            q.all(),
                 (Order(address_id=1,description=u'order 3',isopen=1,user_id=7,id=3), Order(address_id=1,description=u'order 1',isopen=0,user_id=7,id=1)), 
                 (Order(address_id=None,description=u'order 5',isopen=0,user_id=7,id=5), Order(address_id=1,description=u'order 1',isopen=0,user_id=7,id=1)),