]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
lazy load and deferred load operations require the parent object
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 18 Jun 2006 00:56:25 +0000 (00:56 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 18 Jun 2006 00:56:25 +0000 (00:56 +0000)
to be in a Session to do the operation; whereas before the operation
would just return a blank list or None, it now raises an exception.

Session.update() is slightly more lenient if the session to which
the given object was formerly attached to was garbage collected;
otherwise still requires you explicitly remove the instance from
the previous Session.

CHANGES
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/session.py

diff --git a/CHANGES b/CHANGES
index 93727226a14bcb84a098338369025ede32a5680b..c847502277fa3b744fbfa7a6ea84060bb3923982 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,13 @@
 0.2.4
 - try/except when the mapper sets init.__name__ on a mapped class,
 supports python 2.3
+- lazy load and deferred load operations require the parent object
+to be in a Session to do the operation; whereas before the operation
+would just return a blank list or None, it now raises an exception.
+- Session.update() is slightly more lenient if the session to which
+the given object was formerly attached to was garbage collected;
+otherwise still requires you explicitly remove the instance from 
+the previous Session.
 
 0.2.3
 - overhaul to mapper compilation to be deferred.  this allows mappers
index 843bcf8173f2bacb644e168014a9851023352492..e56350cecbfcac480e1081640fac7efc57d1aba2 100644 (file)
@@ -68,20 +68,22 @@ class DeferredColumnProperty(ColumnProperty):
         if not self.localparent.is_assigned(instance):
             return mapper.object_mapper(instance).props[self.key].setup_loader(instance)
         def lazyload():
-            session = sessionlib.object_session(instance)
-            if session is None:
-                return None
-            clause = sql.and_()
-            connection = session.connection(self.parent)
             try:
                 pk = self.parent.pks_by_table[self.columns[0].table]
             except KeyError:
                 pk = self.columns[0].table.primary_key
+
+            clause = sql.and_()
             for primary_key in pk:
                 attr = self.parent._getattrbycolumn(instance, primary_key)
                 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:
@@ -348,18 +350,19 @@ class LazyLoader(PropertyLoader):
         def lazyload():
             params = {}
             allparams = True
-            session = sessionlib.object_session(instance)
             #print "setting up loader, lazywhere", str(self.lazywhere), "binds", self.lazybinds
-            if session is not None:
-                for col, bind in self.lazybinds.iteritems():
-                    params[bind.key] = self.parent._getattrbycolumn(instance, col)
-                    if params[bind.key] is None:
-                        allparams = False
-                        break
-            else:
-                allparams = False
+            for col, bind in self.lazybinds.iteritems():
+                params[bind.key] = self.parent._getattrbycolumn(instance, col)
+                if params[bind.key] is None:
+                    allparams = False
+                    break
+                
             if not allparams:
                 return None
+
+            session = sessionlib.object_session(instance)
+            if session is None:
+                raise exceptions.InvalidRequestError("Parent instance %s is not bound to a Session; lazy load operation of attribute '%s' cannot proceed" % (instance.__class__, self.key))
                 
             # if we have a simple straight-primary key load, use mapper.get()
             # to possibly save a DB round trip
index 7c86fafb506fbb43020ae37fa2d6fb08aeeec452..7508348241e9e5df3bb5e26577f6a0bbf3055a46 100644 (file)
@@ -363,21 +363,21 @@ class Session(object):
         self.uow.register_deleted(obj)
         
     def _attach(self, obj):
-        """given an object, attaches it to this session.  """
+        """Attach the given object to this Session."""
         if getattr(obj, '_sa_session_id', None) != self.hash_key:
             old = getattr(obj, '_sa_session_id', None)
-            if old is not None:
+            if old is not None and _sessions.has_key(old):
                 raise exceptions.InvalidRequestError("Object '%s' is already attached to session '%s' (this is '%s')" % (repr(obj), old, id(self)))
                 
                 # auto-removal from the old session is disabled.  but if we decide to 
                 # turn it back on, do it as below: gingerly since _sessions is a WeakValueDict
                 # and it might be affected by other threads
-                try:
-                    sess = _sessions[old]
-                except KeyError:
-                    sess = None
-                if sess is not None:
-                    sess.expunge(old)
+                #try:
+                #    sess = _sessions[old]
+                #except KeyError:
+                #    sess = None
+                #if sess is not None:
+                #    sess.expunge(old)
             key = getattr(obj, '_instance_key', None)
             if key is not None:
                 self.identity_map[key] = obj