From 84003a8d402c5d7539cf2d53f4061cde62d04413 Mon Sep 17 00:00:00 2001 From: Martijn Faassen Date: Thu, 6 Nov 2008 06:12:11 +0000 Subject: [PATCH] add two new hooks for bulk operations to SessionExtension: * after_bulk_delete * after_bulk_update --- CHANGES | 6 ++++++ lib/sqlalchemy/orm/interfaces.py | 20 ++++++++++++++++++++ lib/sqlalchemy/orm/query.py | 6 ++++++ test/orm/session.py | 12 ++++++++++++ 4 files changed, 44 insertions(+) diff --git a/CHANGES b/CHANGES index a212142986..3bf18cfeba 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,12 @@ CHANGES 0.5.0rc3 ======== - orm + + - Added two new hooks to SessionExtension: after_bulk_delete and + after_bulk_update. after_bulk_delete is called after a bulk delete() + operation on a query. after_bulk_update is called after a bulk update() + operation on a query. + - "not equals" comparisons of simple many-to-one relation to an instance will not drop into an EXISTS clause and will compare foreign key columns instead. diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index bd934ce13b..609ed0ca11 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -307,6 +307,26 @@ class SessionExtension(object): This is called after an add, delete or merge. """ + def after_bulk_update(self, session, query, query_context, result): + """Execute after a bulk update operation to the session. + + This is called after a session.query(...).update() + + `query` is the query object that this update operation was called on. + `query_context` was the query context object. + `result` is the result object returned from the bulk operation. + """ + + def after_bulk_delete(self, session, query, query_context, result): + """Execute after a bulk delete operation to the session. + + This is called after a session.query(...).delete() + + `query` is the query object that this delete operation was called on. + `query_context` was the query context object. + `result` is the result object returned from the bulk operation. + """ + class MapperProperty(object): """Manage the relationship of a ``Mapper`` to a single class attribute, as well as that attribute as it appears on individual diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index ec378d9c6d..aa30f15174 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1348,6 +1348,9 @@ class Query(object): if identity_key in session.identity_map: session._remove_newly_deleted(attributes.instance_state(session.identity_map[identity_key])) + for ext in session.extensions: + ext.after_bulk_delete(session, self, context, result) + return result.rowcount def update(self, values, synchronize_session='expire'): @@ -1442,6 +1445,9 @@ class Query(object): if identity_key in session.identity_map: session.expire(session.identity_map[identity_key], values.keys()) + for ext in session.extensions: + ext.after_bulk_update(session, self, context, result) + return result.rowcount def _compile_context(self, labels=True): diff --git a/test/orm/session.py b/test/orm/session.py index 58c4888a76..f32736b32e 100644 --- a/test/orm/session.py +++ b/test/orm/session.py @@ -898,6 +898,10 @@ class SessionTest(_fixtures.FixtureTest): log.append('after_begin') def after_attach(self, session, instance): log.append('after_attach') + def after_bulk_update(self, session, query, query_context, result): + log.append('after_bulk_update') + def after_bulk_delete(self, session, query, query_context, result): + log.append('after_bulk_delete') sess = create_session(extension = MyExt()) u = User(name='u1') @@ -920,6 +924,14 @@ class SessionTest(_fixtures.FixtureTest): log = [] sess.commit() assert log == ['before_commit', 'after_commit'] + + log = [] + sess.query(User).delete() + assert log == ['after_begin', 'after_bulk_delete'] + + log = [] + sess.query(User).update({'name': 'foo'}) + assert log == ['after_bulk_update'] log = [] sess = create_session(autocommit=False, extension=MyExt(), bind=testing.db) -- 2.47.3