diff options
Diffstat (limited to 'lib/sqlalchemy/orm/session.py')
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 9ac529aeb..2c7fd86d2 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -2380,7 +2380,8 @@ class Session(_SessionClassMethods): transaction.rollback(_capture_exception=True) def bulk_save_objects( - self, objects, return_defaults=False, update_changed_only=True): + self, objects, return_defaults=False, update_changed_only=True, + preserve_order=True): """Perform a bulk save of the given list of objects. The bulk save feature allows mapped objects to be used as the @@ -2443,6 +2444,13 @@ class Session(_SessionClassMethods): When False, all attributes present are rendered into the SET clause with the exception of primary key attributes. + :param preserve_order: when True, the order of inserts and updates + matches exactly the order in which the objects are given. When + False, common types of objects are grouped into inserts + and updates, to allow for more batching opportunities. + + .. versionadded:: 1.3 + .. seealso:: :ref:`bulk_operations` @@ -2452,9 +2460,15 @@ class Session(_SessionClassMethods): :meth:`.Session.bulk_update_mappings` """ + def key(state): + return (state.mapper, state.key is not None) + + obj_states = tuple(attributes.instance_state(obj) for obj in objects) + if not preserve_order: + obj_states = sorted(obj_states, key=key) + for (mapper, isupdate), states in itertools.groupby( - (attributes.instance_state(obj) for obj in objects), - lambda state: (state.mapper, state.key is not None) + obj_states, key ): self._bulk_save_mappings( mapper, states, isupdate, True, |