MikeN
MikeN

Reputation: 46277

Why would a Django model cascade delete fail in the real world?

Given the Django models:


class ContainerOwner(models.Model):
  id = models.IntegerField()

class Container(models.Model):
  owner = models.ForeignKey(ContainerOwner)

If you call .delete() on a "ContainerOwner" object it will cascade delete all of the "Container" objects owned by that 'ContainerOwner'.

But I've found that in my real life django project there are times when this cascade delete seems to fail. It seems to occur sporadically and when the system is under a high volume. So you end up with "Container" objects that have no valid "ContainerOwner" after the "ContainerOwner" has been deleted (this should be impossible, 'Containers' always have a 'ContainerOwner'.)

Has anyone seen this type of failure before and can explain how it is occurring? Can the cascade delete get killed halfway in the process of doing the cascade delete by the application or DB server?


Updates to question based on answer feedback:

1) We are using myisam with MySQL

2) We are using a queryset delete to delete a queryset of "ContainerOwner" objects

3) MySQL backend

4) We have a very common action where a Django queryset of "ContainerOwner" objects is deleted in all at once and all of their "Container" objects should also be deleted. This happens dozens of times a day and we are just noticing that there are these orphan "Container" objects causing application errors. It looks like a very very small percentage of the deletes are failing, like 0.01% of deletions lead to having some orphans.

Upvotes: 3

Views: 1177

Answers (2)

Matthew Schinckel
Matthew Schinckel

Reputation: 35619

If someone else has added a container in the meantime, that has the same ContainerOwner, and you are outside of a transaction, it would fail to delete. You should get an IntegrityError under these circumstances.

Also, if you have any code that is outside of django, and there are other, conflicting database constraints, then these will prevent cascading deletion.

Try checking your database logs, and see why the delete is failing.

Upvotes: 0

Botond Béres
Botond Béres

Reputation: 16673

It's not really possible to answer your actual question, without knowing a lot more details about your application like:

  1. Do you have any custom logic in ContainerOwner.delete() or Container.delete()?
  2. Are you using queryset's delete anywhere, on ContainerOwner?
  3. What database are you using??
  4. The general usage pattern in creating/updating/deleting ContainerOwner/Container objects

But most importantly:

"Container" objects that have no valid "ContainerOwner" after the "ContainerOwner" has been deleted

This should not be possible in the first place on the database level, unless you are missing foreign key constraints or you are using a DB which does not support FK constraints (like MySQL + MYISAM). If it's the former, you should fix that first. If it's the latter, consider switching, depending on how important this actually is for your app.

Upvotes: 2

Related Questions