Commits

Mike Bayer committed a04ef78

turn commit_all into an iterative method

Comments (0)

Files changed (4)

lib/sqlalchemy/orm/loading.py

 from .interfaces import EXT_CONTINUE
 from ..sql import util as sql_util
 from .util import _none_set, state_str
+statelib = util.importlater("sqlalchemy.orm", "state")
 
 _new_runid = util.counter()
 
                     context.refresh_state.dict, query._only_load_props)
             context.progress.pop(context.refresh_state)
 
-        for state, dict_ in context.progress.items():
-            state.commit_all(dict_, session.identity_map)
-
+        statelib.InstanceState.commit_all_states(
+            context.progress.items(),
+            session.identity_map
+        )
 
         for ii, (dict_, attrs) in context.partials.iteritems():
             ii.commit(dict_, attrs)

lib/sqlalchemy/orm/session.py

 from .unitofwork import UOWTransaction
 from .mapper import Mapper
 from .events import SessionEvents
-
+statelib = util.importlater("sqlalchemy.orm", "state")
 import sys
 
 __all__ = ['Session', 'SessionTransaction', 'SessionExtension']
                     state.key = instance_key
 
                 self.identity_map.replace(state)
-                state.commit_all(state.dict, self.identity_map)
+
+        statelib.InstanceState.commit_all_states(
+            ((state, state.dict) for state in states),
+            self.identity_map
+        )
 
         self._register_altered(states)
         # remove from new last, might be the last strong ref

lib/sqlalchemy/orm/state.py

          - the "modified" flag is set to False
          - any "expired" markers/callables for attributes loaded are removed.
 
-        Attributes marked as "expired" can potentially remain "expired" after this step
-        if a value was not populated in state.dict.
+        Attributes marked as "expired" can potentially remain 
+        "expired" after this step if a value was not populated in state.dict.
 
         """
+        self.commit_all_states([(self, dict_)], instance_dict)
 
-        self.committed_state.clear()
-        self.__dict__.pop('_pending_mutations', None)
+    @classmethod
+    def commit_all_states(self, iter, instance_dict=None):
+        """Mass version of commit_all()."""
 
-        callables = self.callables
-        for key in list(callables):
-            if key in dict_ and callables[key] is self:
-                del callables[key]
+        for state, dict_ in iter:
+            state.committed_state.clear()
+            state.__dict__.pop('_pending_mutations', None)
 
-        if instance_dict and self.modified:
-            instance_dict._modified.discard(self)
+            callables = state.callables
+            for key in list(callables):
+                if key in dict_ and callables[key] is state:
+                    del callables[key]
 
-        self.modified = self.expired = False
-        self._strong_obj = None
+            if instance_dict and state.modified:
+                instance_dict._modified.discard(state)
+
+            state.modified = state.expired = False
+            state._strong_obj = None
 
 class InspectAttr(object):
     """Provide inspection interface to an object's state."""

test/aaa_profiling/test_orm.py

         # third call, merge object already present. almost no calls.
 
         @profiling.function_call_count(variance=0.05,
-                versions={'2.7':14, '2.6':14, '2.5':15, '3': 15})
+                versions={'2.7':15, '2.6':15, '2.5':16, '3': 16})
         def go():
             return sess2.merge(p2, load=False)
         p3 = go()