]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
deferred column load could screw up the connection status in
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 14 Jul 2006 21:02:35 +0000 (21:02 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 14 Jul 2006 21:02:35 +0000 (21:02 +0000)
a flush() under some circumstances, this was fixed

CHANGES
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/orm/properties.py
test/orm/objectstore.py

diff --git a/CHANGES b/CHANGES
index 810f2ec9a953e7def0439de71b79bb776a839f38..7fbbe6e0151cfba7fa96be6c39cd5a5aacdefa0a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -23,6 +23,8 @@ this also adds them to activemapper
 database if you supply a __autoload__ = True attribute in your
 mapping inner-class.  Currently this does not support reflecting 
 any relationships.
+- deferred column load could screw up the connection status in 
+a flush() under some circumstances, this was fixed
 
 0.2.5
 - fixed endless loop bug in select_by(), if the traversal hit
index 85e68825f2b14c6917ec31fc52922a7122f31ea6..048c2400988748dcbc76d7ede6504bba1b8d6c51 100644 (file)
@@ -231,11 +231,15 @@ class Connection(Connectable):
         self.__connection = None
         del self.__connection
     def scalar(self, object, parameters=None, **kwargs):
-        row = self.execute(object, parameters, **kwargs).fetchone()
-        if row is not None:
-            return row[0]
-        else:
-            return None
+        result = self.execute(object, parameters, **kwargs)
+        row = result.fetchone()
+        try:
+            if row is not None:
+                return row[0]
+            else:
+                return None
+        finally:
+            result.close()
     def execute(self, object, *multiparams, **params):
         return Connection.executors[type(object).__mro__[-2]](self, object, *multiparams, **params)
     def execute_default(self, default, **kwargs):
index 997636b49bbe746283a4b15e9be060c094816cc7..752ea23af1960ae1f851e06d49ac0f05817d3023 100644 (file)
@@ -79,16 +79,15 @@ class DeferredColumnProperty(ColumnProperty):
                 if not attr:
                     return None
                 clause.clauses.append(primary_key == attr)
-
             session = sessionlib.object_session(instance)
             if session is None:
                 raise exceptions.InvalidRequestError("Parent instance %s is not bound to a Session; deferred load operation of attribute '%s' cannot proceed" % (instance.__class__, self.key))
-            connection = session.connection(self.parent)
-            
-            try:
-                if self.group is not None:
-                    groupcols = [p for p in self.localparent.props.values() if isinstance(p, DeferredColumnProperty) and p.group==self.group]
-                    row = connection.execute(sql.select([g.columns[0] for g in groupcols], clause, use_labels=True), None).fetchone()
+
+            if self.group is not None:
+                groupcols = [p for p in self.localparent.props.values() if isinstance(p, DeferredColumnProperty) and p.group==self.group]
+                result = session.execute(self.localparent, sql.select([g.columns[0] for g in groupcols], clause, use_labels=True), None)
+                try:
+                    row = result.fetchone()
                     for prop in groupcols:
                         if prop is self:
                             continue
@@ -97,10 +96,11 @@ class DeferredColumnProperty(ColumnProperty):
                         instance.__dict__[prop.key] = row[prop.columns[0]]
                         sessionlib.attribute_manager.init_instance_attribute(instance, prop.key, uselist=False)
                     return row[self.columns[0]]    
-                else:
-                    return connection.scalar(sql.select([self.columns[0]], clause, use_labels=True),None)
-            finally:
-                connection.close()
+                finally:
+                    result.close()
+            else:
+                return session.scalar(self.localparent, sql.select([self.columns[0]], clause, use_labels=True),None)
+
         return lazyload
     def setup(self, key, statement, **options):
         pass
index 237c4b554587f63effd213635f712f823bd85c55..19e5faccb8c50f1ad1c461194234643e2297ef20 100644 (file)
@@ -612,6 +612,15 @@ class SaveTest(SessionTest):
         l = AddressUser.mapper.selectone()
         self.assert_(l.user_id == au.user_id and l.address_id == au.address_id)
     
+    def testdeferred(self):
+        """test that a deferred load within a flush() doesnt screw up the connection"""
+        mapper(User, users, properties={
+            'user_name':deferred(users.c.user_name)
+        })
+        u = User()
+        u.user_id=42
+        ctx.current.flush()
+        
     def testmultitable(self):
         """tests a save of an object where each instance spans two tables. also tests
         redefinition of the keynames for the column properties."""