]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
relation.order_by requires _literal_as_column conversion as well
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 29 Jul 2008 19:49:46 +0000 (19:49 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 29 Jul 2008 19:49:46 +0000 (19:49 +0000)
CHANGES
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/session.py
test/ext/declarative.py

diff --git a/CHANGES b/CHANGES
index 100626f1a2df52d1cf68cf66f5468b4189295270..4af45f143f8863a5bfcceeac87cc30f5640242ac 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -59,6 +59,9 @@ CHANGES
     - 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
index 18e816546d0002f18227c84eac3407526e5decff..41e191312e7082aab21ee5af3ab25393b917e56b 100644 (file)
@@ -16,7 +16,6 @@ import inspect, StringIO
 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.
 
@@ -1497,7 +1496,6 @@ class ResultProxy(object):
     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
index 51e0631e50a9f59997799994b6da9ae239014718..8c6a92a1ebe0142fafc6ec055485d408d6b761e5 100644 (file)
@@ -533,6 +533,9 @@ class PropertyLoader(StrategizedProperty):
             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))
 
index fbfcd51c6b29cc4f95fc435e315002c162183596..944fc9c5dd5a6c66d036fa7d1327477269ee6c99 100644 (file)
@@ -9,7 +9,6 @@
 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 (
@@ -902,6 +901,7 @@ class Session(object):
         """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()
@@ -941,6 +941,7 @@ class Session(object):
 
     def expire_all(self):
         """Expires all persistent instances within this Session."""
+
         for state in self.identity_map.all_states():
             _expire_state(state, None)
 
index 6cf553a375e1fb9a65582d7a59e5de17cda41476..31f0dfd2d85b8c0f79810fd6375ee5c2f6ca2717 100644 (file)
@@ -2,8 +2,8 @@ import testenv; testenv.configure_for_tests()
 
 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
 
@@ -205,7 +205,37 @@ class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults):
         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'