I am using a MapperExtension to implement trigger-like functions in my
app and needed an after_delete event. Attached is a patch which
implements the needed changes to Mapper.py (also updates
adv_datamapping.myt docs).
Sean Cazzell
Index: doc/build/content/adv_datamapping.txt
===================================================================
--- doc/build/content/adv_datamapping.txt (revision 1492)
+++ doc/build/content/adv_datamapping.txt (working copy)
@@ -787,6 +787,8 @@
"""called after an object instance has been INSERTed"""
def before_delete(self, mapper, connection, instance):
"""called before an object instance is DELETEed"""
+ def after_delete(self, mapper, connection, instance):
+ """called after an object instance is DELETEed"""
To use MapperExtension, make your own subclass of it and just send it off to a mapper:
Index: lib/sqlalchemy/orm/mapper.py
===================================================================
--- lib/sqlalchemy/orm/mapper.py (revision 1492)
+++ lib/sqlalchemy/orm/mapper.py (working copy)
@@ -682,6 +682,7 @@
if not self._has_pks(table):
continue
delete = []
+ deleted_objects = []
for obj in objects:
params = {}
if not hasattr(obj, "_instance_key"):
@@ -693,6 +694,7 @@
if self.version_id_col is not None:
params[self.version_id_col.key] = self._getattrbycolumn(obj, self.version_id_col)
self.extension.before_delete(self, connection, obj)
+ deleted_objects.append(obj)
if len(delete):
clause = sql.and_()
for col in self.pks_by_table[table]:
@@ -703,6 +705,8 @@
c = connection.execute(statement, delete)
if c.supports_sane_rowcount() and c.rowcount != len(delete):
raise exceptions.FlushError("ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (c.cursor.rowcount, len(delete)))
+ for obj in deleted_objects:
+ self.extension.after_delete(self, connection, obj)
def _has_pks(self, table):
try:
@@ -1078,6 +1082,10 @@
"""called before an object instance is DELETEed"""
if self.next is not None:
self.next.before_delete(mapper, connection, instance)
+ def after_delete(self, mapper, connection, instance):
+ """called after an object instance is DELETEed"""
+ if self.next is not None:
+ self.next.after_delete(mapper, connection, instance)
class TranslatingDict(dict):
"""a dictionary that stores ColumnElement objects as keys. incoming ColumnElement