Commits

Mike Bayer committed 1b5d6c4

relation.order_by requires _literal_as_column conversion as well

Comments (0)

Files changed (5)

     - Class-bound attributes sent as arguments to 
       relation()'s remote_side and foreign_keys parameters 
       are now accepted, allowing them to be used with declarative.
+      Additionally fixed bugs involving order_by being
+      specified as a class-bound attribute in conjunction
+      with eager loading.
       
 - mysql
     - Quoting of MSEnum values for use in CREATE TABLE is now

lib/sqlalchemy/engine/base.py

 from sqlalchemy import exc, schema, util, types, log
 from sqlalchemy.sql import expression
 
-
 class Dialect(object):
     """Define the behavior of a specific database and DB-API combination.
 
     def _create_key_cache(self):
         # local copies to avoid circular ref against 'self'
         props = self.__props
-        context = self.context
         def lookup_key(key):
             """Given a key, which could be a ColumnElement, string, etc.,
             matches it to the appropriate key we got from the result set's

lib/sqlalchemy/orm/properties.py

             if callable(getattr(self, attr)):
                 setattr(self, attr, getattr(self, attr)())
         
+        if self.order_by:
+            self.order_by = [expression._literal_as_column(x) for x in util.to_list(self.order_by)]
+        
         self._foreign_keys = set(expression._literal_as_column(x) for x in util.to_set(self._foreign_keys))
         self.remote_side = set(expression._literal_as_column(x) for x in util.to_set(self.remote_side))
 

lib/sqlalchemy/orm/session.py

 import weakref
 
 import sqlalchemy.exceptions as sa_exc
-import sqlalchemy.orm.attributes
 from sqlalchemy import util, sql, engine
 from sqlalchemy.sql import util as sql_util, expression
 from sqlalchemy.orm import (
         """Return a new ``Query`` object corresponding to this ``Session``."""
 
         return self._query_cls(entities, self, **kwargs)
+
     def _autoflush(self):
         if self.autoflush and (self.transaction is None or self.transaction.autoflush):
             self.flush()
 
     def expire_all(self):
         """Expires all persistent instances within this Session."""
+
         for state in self.identity_map.all_states():
             _expire_state(state, None)
 

test/ext/declarative.py

 
 from sqlalchemy.ext import declarative as decl
 from testlib import sa, testing
-from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, ForeignKeyConstraint
-from testlib.sa.orm import relation, create_session, class_mapper
+from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, ForeignKeyConstraint, asc
+from testlib.sa.orm import relation, create_session, class_mapper, eagerload
 from testlib.testing import eq_
 from orm._base import ComparableEntity
 
         a1 = sess.query(Address).filter(Address.email == 'two').one()
         eq_(a1, Address(email='two'))
         eq_(a1.user, User(name='u1'))
+    
+    def test_eager_order_by(self):
+        class Address(Base, ComparableEntity):
+            __tablename__ = 'addresses'
 
+            id = Column('id', Integer, primary_key=True)
+            email = Column('email', String(50))
+            user_id = Column('user_id', Integer, ForeignKey('users.id'))
+
+        class User(Base, ComparableEntity):
+            __tablename__ = 'users'
+
+            id = Column('id', Integer, primary_key=True)
+            name = Column('name', String(50))
+            addresses = relation("Address", order_by=Address.email)
+
+        Base.metadata.create_all()
+        u1 = User(name='u1', addresses=[
+            Address(email='two'),
+            Address(email='one'),
+        ])
+        sess = create_session()
+        sess.save(u1)
+        sess.flush()
+        sess.clear()
+        eq_(sess.query(User).options(eagerload(User.addresses)).all(), [User(name='u1', addresses=[
+            Address(email='one'),
+            Address(email='two'),
+        ])])
+
+            
     def test_as_declarative(self):
         class User(ComparableEntity):
             __tablename__ = 'users'
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.