1

I have a fairly large production database system, based on a large hierarchy of nodes each with a 10+ associated models. If someone deletes a node fairly high in the tree, there can be thousands of models deleted and if that deletion was a mistake, restoring them can be very difficult. I'm looking for a way to give me an easy 'undo' option.

I've tried using Django-reversion, but it seems like in order to get the functionality I want (easily reverting a large cascade delete) it needs to store a bunch of information with each revision. When I created initial revisions, the process is less than 10% done and it's already using 8GB in my database, which is not going to work for me.

So, is there a standard solution for this problem? Or a way to customize Django-reversions to fit my use case?

The Bearded Templar
  • 671
  • 1
  • 7
  • 16
  • Are we talking about deleting with a query or somoene clicking delete on the webpage? That is, what behaviour do you need to revert. – Jakub Kania May 30 '16 at 16:42
  • @JakubKania Clicking delete on the webpage. Basically a user deletes a high level node, it cascades a bunch of stuff, I get an email saying 'Oops, I need the data back'. – The Bearded Templar May 30 '16 at 16:55
  • Besides Jakub's answer that properly describes your options, if you ever need to prevent this whole situation entirely, you could unset the cascade behaviour that django has as default, by setting `on_delete` option on foreign keys. Documentation https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.on_delete – stelios Sep 05 '16 at 10:15

1 Answers1

3

What you're looking for is called a soft delete. Add a column named deleted with a value of false to the table. Now when you want to do a "delete" instead change the column deleted to true. Update all the code not to show the rows marked as deleted (or move the database table and replace it with a view that doesn't show them). Change all the unique constraints to have a filter WHERE deleted = false so you won't have a problem with not being able to add something similar to what user can't see in the system.

As for the cascades you have two options. Either do an ON UPDATE trigger that will update the child rows or add the deleted column to the FK and define it as ON UPDATE CASCADE.

You'll get the whole reverse functionality at a cost of one extra row (and not being able to delete stuff to save space unless you do it manually).

Jakub Kania
  • 15,665
  • 2
  • 37
  • 47