[PEAK] Cascading delete
Phillip J. Eby
pje at telecommunity.com
Fri Jul 22 11:57:43 EDT 2005
At 08:41 PM 7/21/2005 +0000, Tiago Cogumbreiro wrote:
>Hi again list,
>My data managers support a "delete-oids" event, where its listeners
>can know when and which oids are removed from a given DM.
As I said before, you should do this by overriding *remove*, not
_delete_oids. Cascading delete is a model-level event, not a storage-level
>Is it a good policy to use the '_remove_oids' to propagate the removal
>of oids directly?
As I said in my previous reply to you, no. Absolutely not.
>My problem is: I have a DM that contains entries from a "foreign" DM
>which I do not know its implementation and don't want to do a:
>for oid in oids:
> obj = self.get (oid)
> self.ForeignDM.remove (obj.bar)
> obj.bar = None
What you want to do is:
removed = binding.Make(events.Broadcaster)
def remove(self, ob):
Then have your DMs with foreign key references to this DM should subscribe
methods to the removed event that search for the corresponding child
objects and remove() them.
*None* of this should be done at the _delete_oids() level, as cascading
delete is a feature of the domain model, not the storage level.
Now, for this to work correctly you are going to want to ensure that the
foreign key subscribers are always flushed before the primary DM
flushes. You may wish to then add something like:
flushing = binding.Make(events.Broadcaster)
def flush(self, ob=None):
if ob is None: # only send if we're flushing generally
And then subscribe the foreign key DMs to 'flushing' in order to trigger
flushes of their own. As long as the foreign key DMs use the primary DM's
"oidFor()" method to obtain their foreign key values, this will ensure that
referential integrity is preserved. (Because "oidFor()" will ensure that
its argument has been INSERTed in the primary table before it returns the
foreign key value.)
More information about the PEAK