]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- merged some more of the SessionTransaction connection-bound checks from 0.4
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 18 Jul 2007 18:51:35 +0000 (18:51 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 18 Jul 2007 18:51:35 +0000 (18:51 +0000)
- _BinaryExpression.compare() checks for a base set of "commutative" operators and checks for itself in reverse if so
- added ORM-based unit test for the above, fixes [ticket:664]

CHANGES
lib/sqlalchemy/orm/session.py
lib/sqlalchemy/sql.py
test/orm/lazy_relations.py
test/orm/session.py

diff --git a/CHANGES b/CHANGES
index 3f7f8ed31950ba8eee179f7b5e1f0b6d45c72e27..7f69e89e523c29f53244de823f4a95e1daad4ba1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,10 +1,12 @@
 0.3.10
 - sql
     - got connection-bound metadata to work with implicit execution
-    - cleanup to connection-bound sessions, SessionTransaction
     - foreign key specs can have any chararcter in their identifiers
      [ticket:667]
-    
+    - added commutativity-awareness to binary clause comparisons to
+      each other, improves ORM lazy load optimization [ticket:664]
+- orm
+    - cleanup to connection-bound sessions, SessionTransaction
 - postgres
     - fixed max identifier length (63) [ticket:571]
 
index 9e504c104dde55d37c55e3b877a9847dcaf98b66..4e7453d84ed77eba61ce88d3947aa381317ecf3e 100644 (file)
@@ -39,9 +39,10 @@ class SessionTransaction(object):
     def add(self, bind):
         if self.parent is not None:
             return self.parent.add(bind)
-            
+
         if self.connections.has_key(bind.engine):
-            raise exceptions.InvalidRequestError("Session already has a Connection associated for the given Connection's Engine")
+            raise exceptions.InvalidRequestError("Session already has a Connection associated for the given %sEngine" % (isinstance(bind, engine.Connection) and "Connection's " or ""))
+            
         return self.get_or_add(bind)
 
     def get_or_add(self, bind):
@@ -57,6 +58,8 @@ class SessionTransaction(object):
         else:
             e = bind.engine
             c = bind
+            if e in self.connections:
+                raise exceptions.InvalidRequestError("Session already has a Connection associated for the given Connection's Engine")
 
         self.connections[bind] = self.connections[e] = (c, c.begin(), c is not bind)
         return self.connections[bind][0]
index 4c720dfa2e1b1f395d3cb6d83c964e5d466a3252..fecb5350b7c8b2bf3692ee473e7d9814775ff641 100644 (file)
@@ -2210,7 +2210,13 @@ class _BinaryExpression(ColumnElement):
 
         return (
             isinstance(other, _BinaryExpression) and self.operator == other.operator and
-            self.left.compare(other.left) and self.right.compare(other.right)
+                (
+                    self.left.compare(other.left) and self.right.compare(other.right)
+                    or (
+                        self.operator in ['=', '!=', '+', '*'] and
+                        self.left.compare(other.right) and self.right.compare(other.left)
+                    )
+                )
         )
         
     def self_group(self, against=None):
index 5accb74713b6e882226fb8581912024d2cac8dce..e9d77e09c6df6f346f450dd79ce12f0f141b8280 100644 (file)
@@ -230,23 +230,29 @@ class LazyTest(QueryTest):
     def test_uses_get(self):
         """test that a simple many-to-one lazyload optimizes to use query.get()."""
 
-        mapper(Address, addresses, properties = dict(
-            user = relation(mapper(User, users), lazy=True)
-        ))
+        for pj in (
+            None,
+            users.c.id==addresses.c.user_id,
+            addresses.c.user_id==users.c.id
+        ):
+            mapper(Address, addresses, properties = dict(
+                user = relation(mapper(User, users), lazy=True, primaryjoin=pj)
+            ))
         
-        sess = create_session()
+            sess = create_session()
         
-        # load address
-        a1 = sess.query(Address).filter_by(email_address="ed@wood.com").one()
+            # load address
+            a1 = sess.query(Address).filter_by(email_address="ed@wood.com").one()
         
-        # load user that is attached to the address
-        u1 = sess.query(User).get(8)
+            # load user that is attached to the address
+            u1 = sess.query(User).get(8)
+        
+            def go():
+                # lazy load of a1.user should get it from the session
+                assert a1.user is u1
+            self.assert_sql_count(testbase.db, go, 0)
+            clear_mappers()
         
-        def go():
-            # lazy load of a1.user should get it from the session
-            assert a1.user is u1
-        self.assert_sql_count(testbase.db, go, 0)
-
     def test_many_to_one(self):
         mapper(Address, addresses, properties = dict(
             user = relation(mapper(User, users), lazy=True)
index eec3e0ca203b6af7bab28887e1fc250faa41af8a..762722ecc8d253b82dc1ca9a11da4777063e1075 100644 (file)
@@ -93,7 +93,26 @@ class SessionTest(AssertMixin):
         u = User()
         sess.save(u)
         sess.flush()
-        assert transaction.get_or_add(testbase.db) is trans2.get_or_add(testbase.db) #is transaction.get_or_add(c) is trans2.get_or_add(c) is c
+        assert transaction.get_or_add(testbase.db) is trans2.get_or_add(testbase.db) is transaction.get_or_add(c) is trans2.get_or_add(c) is c
+
+        try:
+            transaction.add(testbase.db.connect())
+            assert False
+        except exceptions.InvalidRequestError, e: 
+            assert str(e) == "Session already has a Connection associated for the given Connection's Engine"
+
+        try:
+            transaction.get_or_add(testbase.db.connect())
+            assert False
+        except exceptions.InvalidRequestError, e: 
+            assert str(e) == "Session already has a Connection associated for the given Connection's Engine"
+
+        try:
+            transaction.add(testbase.db)
+            assert False
+        except exceptions.InvalidRequestError, e: 
+            assert str(e) == "Session already has a Connection associated for the given Engine"
+
         trans2.commit()
         transaction.rollback()
         assert len(sess.query(User).select()) == 0