summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/session.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-08-14 19:47:23 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-08-15 15:53:38 -0400
commit591f2e4ed2d455cb2c5b9ece43d79fde4b109510 (patch)
tree9a4a03b5d36725dda83c4f67604c63cb062f3cf2 /lib/sqlalchemy/orm/session.py
parent6bc676f56d57d5ea4dc298f63d0e3a77c0f4a4a1 (diff)
downloadsqlalchemy-591f2e4ed2d455cb2c5b9ece43d79fde4b109510.tar.gz
- change to be represented as two very fast bulk_insert() and bulk_update() methods
Diffstat (limited to 'lib/sqlalchemy/orm/session.py')
-rw-r--r--lib/sqlalchemy/orm/session.py57
1 files changed, 29 insertions, 28 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index 546355611..3199a4332 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -20,6 +20,7 @@ from .base import (
_class_to_mapper, _state_mapper, object_state,
_none_set, state_str, instance_str
)
+import itertools
from .unitofwork import UOWTransaction
from . import state as statelib
import sys
@@ -482,7 +483,8 @@ class Session(_SessionClassMethods):
'__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
'close', 'commit', 'connection', 'delete', 'execute', 'expire',
'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
- 'is_modified', 'bulk_save_objects', 'bulk_save_mappings',
+ 'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
+ 'bulk_update_mappings',
'merge', 'query', 'refresh', 'rollback',
'scalar')
@@ -2034,42 +2036,41 @@ class Session(_SessionClassMethods):
transaction.rollback(_capture_exception=True)
def bulk_save_objects(self, objects):
- self._bulk_save((attributes.instance_state(obj) for obj in objects))
+ for (mapper, isupdate), states in itertools.groupby(
+ (attributes.instance_state(obj) for obj in objects),
+ lambda state: (state.mapper, state.key is not None)
+ ):
+ if isupdate:
+ self.bulk_update_mappings(mapper, (s.dict for s in states))
+ else:
+ self.bulk_insert_mappings(mapper, (s.dict for s in states))
- def bulk_save_mappings(self, mapper, mappings):
- mapper = class_mapper(mapper)
+ def bulk_insert_mappings(self, mapper, mappings):
+ self._bulk_save_mappings(mapper, mappings, False)
- self._bulk_save((
- statelib.MappingState(mapper, mapping)
- for mapping in mappings)
- )
+ def bulk_update_mappings(self, mapper, mappings):
+ self._bulk_save_mappings(mapper, mappings, True)
- def _bulk_save(self, states):
+ def _bulk_save_mappings(self, mapper, mappings, isupdate):
+ mapper = _class_to_mapper(mapper)
self._flushing = True
flush_context = UOWTransaction(self)
- if self.dispatch.before_bulk_save:
- self.dispatch.before_bulk_save(
- self, flush_context, states)
-
flush_context.transaction = transaction = self.begin(
subtransactions=True)
try:
- self._warn_on_events = True
- try:
- flush_context.bulk_save(states)
- finally:
- self._warn_on_events = False
-
- self.dispatch.after_bulk_save(
- self, flush_context, states
- )
-
- flush_context.finalize_flush_changes()
-
- self.dispatch.after_bulk_save_postexec(
- self, flush_context, states)
-
+ if isupdate:
+ self.dispatch.before_bulk_update(
+ self, flush_context, mapper, mappings)
+ flush_context.bulk_update(mapper, mappings)
+ self.dispatch.after_bulk_update(
+ self, flush_context, mapper, mappings)
+ else:
+ self.dispatch.before_bulk_insert(
+ self, flush_context, mapper, mappings)
+ flush_context.bulk_insert(mapper, mappings)
+ self.dispatch.after_bulk_insert(
+ self, flush_context, mapper, mappings)
transaction.commit()
except: