1. idank
  2. sqlalchemy

Commits

Mike Bayer  committed d99ca96

- MapperExtension.before_update() and after_update() are now called
symmetrically; previously, an instance that had no modified column
attributes (but had a relation() modification) could be called with
before_update() but not after_update() [ticket:907]

  • Participants
  • Parent commits f8a1089
  • Branches default

Comments (0)

Files changed (3)

File CHANGES

View file
      instance of the extension for both mappers.
      [ticket:490]
 
+   - MapperExtension.before_update() and after_update() are now called
+     symmetrically; previously, an instance that had no modified column
+     attributes (but had a relation() modification) could be called with 
+     before_update() but not after_update() [ticket:907]
+     
    - columns which are missing from a Query's select statement
      now get automatically deferred during load.
      

File lib/sqlalchemy/orm/mapper.py

View file
 
         if not postupdate:
             # call after_XXX extensions
-            for state, connection in inserted_objects:
+            for state, connection, has_identity in tups:
                 mapper = _state_mapper(state)
-                if 'after_insert' in mapper.extension.methods:
-                    mapper.extension.after_insert(mapper, connection, state.obj())
-
-            for state, connection in updated_objects:
-                mapper = _state_mapper(state)
-                if 'after_update' in mapper.extension.methods:
-                    mapper.extension.after_update(mapper, connection, state.obj())
+                if not has_identity:
+                    if 'after_insert' in mapper.extension.methods:
+                        mapper.extension.after_insert(mapper, connection, state.obj())
+                else:
+                    if 'after_update' in mapper.extension.methods:
+                        mapper.extension.after_update(mapper, connection, state.obj())
     
     def _postfetch(self, connection, table, state, resultproxy, params, value_params):
         """After an ``INSERT`` or ``UPDATE``, assemble newly generated

File test/orm/mapper.py

View file
         self.assertEquals(methods, ['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'get', 
             'translate_row', 'create_instance', 'populate_instance', 'before_update', 'after_update', 'before_delete', 'after_delete'])
 
+    def test_after_with_no_changes(self):
+        # test that after_update is called even if no cols were updated
+        
+        mapper(Item, orderitems, extension=Ext() , properties={
+            'keywords':relation(Keyword, secondary=itemkeywords)
+        })
+        mapper(Keyword, keywords, extension=Ext() )
+        
+        sess = create_session()
+        i1 = Item()
+        k1 = Keyword('blue')
+        sess.save(i1)
+        sess.save(k1)
+        sess.flush()
+        self.assertEquals(methods, ['before_insert', 'after_insert', 'before_insert', 'after_insert'])
+
+        methods[:] = []
+        i1.keywords.append(k1)
+        sess.flush()
+        self.assertEquals(methods, ['before_update', 'after_update'])
+        
+        
     def test_inheritance_with_dupes(self):
         # test using inheritance, same extension on both mappers
         class AdminUser(User):