From 7fac6542c5b6501ef23e8b79d50cc748de573d81 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 15 Oct 2007 17:24:08 +0000 Subject: - inline optimizations added to locate_dirty() which can greatly speed up repeated calls to flush(), as occurs with autoflush=True [ticket:816] --- lib/sqlalchemy/orm/unitofwork.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'lib/sqlalchemy/orm/unitofwork.py') diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 39387b4cf..7a443b331 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -156,7 +156,14 @@ class UnitOfWork(object): either contain changes or are marked as deleted. """ - return util.Set([x for x in self.identity_map.values() if x not in self.deleted and attribute_manager.is_modified(x)]) + # a little bit of inlining for speed + return util.Set([x for x in self.identity_map.values() + if x not in self.deleted + and ( + x._state.modified + or (getattr(x.__class__, '_sa_has_mutable_scalars', False) and attribute_manager._is_modified(x._state)) + ) + ]) def flush(self, session, objects=None): """create a dependency tree of all pending SQL operations within this unit of work and execute.""" @@ -166,6 +173,12 @@ class UnitOfWork(object): # communication with the mappers and relationships to fire off SQL # and synchronize attributes between related objects. + # detect persistent objects that have changes + dirty = self.locate_dirty() + + if len(dirty) == 0 and len(self.deleted) == 0 and len(self.new) == 0: + return + flush_context = UOWTransaction(self, session) if session.extension is not None: @@ -178,10 +191,7 @@ class UnitOfWork(object): else: # or just everything objset = util.Set(self.identity_map.values()).union(self.new) - - # detect persistent objects that have changes - dirty = self.locate_dirty() - + # store objects whose fate has been decided processed = util.Set() @@ -197,6 +207,9 @@ class UnitOfWork(object): for obj in self.deleted.intersection(objset).difference(processed): flush_context.register_object(obj, isdelete=True) + if len(flush_context.tasks) == 0: + return + session.create_transaction(autoflush=False) flush_context.transaction = session.transaction try: -- cgit v1.2.1