]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Generalized the IdentityManagedState._instance_dict() callable
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 5 Jan 2009 15:34:09 +0000 (15:34 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 5 Jan 2009 15:34:09 +0000 (15:34 +0000)
to the IdentityMap class so that Weak/StrongInstanceDict both
have the same behavior wrt the state referencing the map
- Fixed bug when using weak_instance_map=False where modified
events would not be intercepted for a flush(). [ticket:1272]

CHANGES
lib/sqlalchemy/orm/identity.py
test/orm/session.py

diff --git a/CHANGES b/CHANGES
index bd0bd870a4d608f7044d1961c87053a01c8e7bde..f26d70e412404502f4a376855a652db3ea8317bc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -81,6 +81,9 @@ CHANGES
       next compile() call.  This issue occurs frequently
       when using declarative.
 
+    - Fixed bug when using weak_instance_map=False where modified
+      events would not be intercepted for a flush(). [ticket:1272]
+      
     - Fixed some deep "column correspondence" issues which could
       impact a Query made against a selectable containing
       multiple versions of the same table, as well as 
index 7d3856a17819f14c85bbad36d95ac72ef24c3a42..0753ea991f40bf8b9611b7108eeca9fea53bd55f 100644 (file)
@@ -14,6 +14,7 @@ class IdentityMap(dict):
     def __init__(self):
         self._mutable_attrs = {}
         self.modified = False
+        self._wr = weakref.ref(self)
         
     def add(self, state):
         raise NotImplementedError()
@@ -28,12 +29,16 @@ class IdentityMap(dict):
         raise NotImplementedError("IdentityMap uses remove() to remove data")
         
     def _manage_incoming_state(self, state):
+        state._instance_dict = self._wr
+        
         if state.modified:  
             self.modified = True
         if state.manager.mutable_attributes:
             self._mutable_attrs[state] = True
     
     def _manage_removed_state(self, state):
+        del state._instance_dict
+        
         if state in self._mutable_attrs:
             del self._mutable_attrs[state]
             
@@ -72,10 +77,6 @@ class IdentityMap(dict):
         
 class WeakInstanceDict(IdentityMap):
 
-    def __init__(self):
-        IdentityMap.__init__(self)
-        self._wr = weakref.ref(self)
-
     def __getitem__(self, key):
         state = dict.__getitem__(self, key)
         o = state.obj()
@@ -107,7 +108,6 @@ class WeakInstanceDict(IdentityMap):
                 raise AssertionError("A conflicting state is already present in the identity map for key %r" % state.key)
         else:
             dict.__setitem__(self, state.key, state)
-            state._instance_dict = self._wr
             self._manage_incoming_state(state)
     
     def remove_key(self, key):
@@ -117,13 +117,11 @@ class WeakInstanceDict(IdentityMap):
     def remove(self, state):
         if dict.pop(self, state.key) is not state:
             raise AssertionError("State %s is not present in this identity map" % state)
-        del state._instance_dict
         self._manage_removed_state(state)
     
     def discard(self, state):
         if self.contains_state(state):
             dict.__delitem__(self, state.key)
-            del state._instance_dict
             self._manage_removed_state(state)
         
     def get(self, key, default=None):
index 782688e13cc2676a8b9a9d7a90d208278351da65..0fdd9daf1957d49c7b81d5e18ae7d627444d1ccd 100644 (file)
@@ -785,6 +785,14 @@ class SessionTest(_fixtures.FixtureTest):
         gc.collect()
         assert len(s.identity_map) == 1
 
+        user = s.query(User).one()
+        assert not s.identity_map.modified
+        user.name = 'u2'
+        assert s.identity_map.modified
+        s.flush()
+        assert users.select().execute().fetchall() == [(1, 'u2')]
+        
+        
     @testing.resolve_artifact_names
     def test_prune(self):
         s = create_session(weak_identity_map=False)