Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django on_delete=models.CASCADE has no effect at SQL level

Tags:

My models.py file contains:

class User(models.Model):
    email = models.CharField(max_length=100, unique=True)
    password = models.CharField(max_length=100)
    create_time = models.DateTimeField(auto_now_add=True)

class Session(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    token = models.CharField(max_length=100, unique=True)

When i command python manage.py makemigrations and then command python manage.py sqlmigrate <app_name> <migration_name> i don't see anything that says "ON DELETE=CASCADE"

However, the migrations work without failure when i type python manage.py migrate.

Now, if i go to the mysql table (using SequelPro) and try to delete a row for a user who currently has a session entry, i get the following error: "One row was not removed. Reload the table to be sure that the contents have not changed in the meantime. Check the Console for possible errors inside the primary key(s) of this table!".

Now, when i go to the session table and delete the sessions of this user and then try to delete the user's row from the user table, it deletes properly. This indicates ON DELETE = CASCADE is not actually working at the MySQL level.

How can i correct it?

like image 662
Rakib Avatar asked Mar 03 '16 18:03

Rakib


People also ask

What does On_delete models Cascade do in Django?

When we set the on_delete parameter as CASCADE, deleting the reference object will also delete the referred object. This option is most useful in many relationships. Suppose a post has comments; when the Post is deleted, all the comments on that Post will automatically delete.

What does Django DB models model ForeignKey On_delete protect do?

The PROTECT argument of the ForeignKey on_delete option prevents the referenced object from being deleted if it already has an object referencing it in the database. Put simply, Django will prevent a post from deletion if it already has comments.

What is On_delete Cascade?

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.


1 Answers

From the docs (emphasis mine):

ForeignKey.on_delete

When an object referenced by a ForeignKey is deleted, Django will emulate the behavior of the SQL constraint specified by the on_delete argument.

Django does not actually set an ON DELETE clause in the database. If you need one, you can add one manually using a RunSQL operation. Be sure to use the same index name, or keep the original index, or you might run into errors later on.

like image 110
knbk Avatar answered Oct 08 '22 17:10

knbk