Added support for Database Level Cascades

80 views
Skip to first unread message

Akash Sen

unread,
May 13, 2023, 10:35:01 AM5/13/23
to Django developers (Contributions to Django itself)
Added support for Database Level Cascades

PR link : https://github.com/django/django/pull/16851

Ref discussion : https://groups.google.com/g/django-developers/c/Sxj7eS7-8SQ/m/jaM1rPbZEQAJ

Approach :

The on_delete argument for ForeignKey class now supports an extra option DB_CASCADE this will behave like DO_NOTHING in Django, but leverage  the Database level cascading options supported by SQL.

A new optional ar gument named  on_delete_db is also passed to the ForeignKey. This will specify the type of database level cascading we are looking for if the on_delete is set to DB_CASCADE. Supported values of the on_delete_db argument can be the following:

ON_DELETE_DB_CHOICES.DO_NOTHING_DB : Does nothing, used as default value.
ON_DELETE_DB_CHOICES.CASCADE_DB : Deletes the child on parent deletion.
ON_DELETE_DB_CHOICES.RESTRICT_DB : Prevent the deletion if child exists.
ON_DELETE_DB_CHOICES.SET_NULL_DB : Set the value to null in child table.

This will modify the SQL query during foreignkey generation.

Checks performed :
1. on_delete = DB_CASCADE and the model containing the field has a non abstract parent model. As inherited the model contains a parent_ptr with in-python cascading options,(OneToOneField with on_delete=models.CASCADE)  both cannot be used  together.
Code : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/django/db/models/fields/related.py#L1041
Related testcase : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/tests/db_cascade_checks/tests.py#L93

2. on_delete = DB_CASCADE and the model containing generic foreign keys or generic relation. In that case we prevent using DB_CASCADE too.
Code : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/django/db/models/fields/related.py#L1060
Related testcase : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/tests/db_cascade_checks/tests.py#L144

3. Both on_delete and on_delete_db are specified. In order to specify the value of on_delete_db, on_delete must be set to DB_CASCADE.
Code : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/django/db/models/fields/related.py#L1137
Related testcase : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/tests/db_cascade_checks/tests.py#L11

4. on_delete_db is set to SET_NULL_DB but the field is not nullable.
Code : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/django/db/models/fields/related.py#L1150
Related testcase : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/tests/db_cascade_checks/tests.py#L66

5. Restricting the use of normal cascading if the foreignkey parent uses DB_CASCADING as this will generate untracable integrity errors.
Code :  1. https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/django/db/models/fields/related.py#L1104
              2. https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/django/db/models/fields/related.py#L1162
Related testcase : https://github.com/django/django/blob/04df10e20853c8e549deddf46fac8c289e265225/tests/db_cascade_checks/tests.py#L33

Harro

unread,
May 14, 2023, 2:15:56 AM5/14/23
to Django developers (Contributions to Django itself)
I have just one question, will this still trigger on delete signals for cascaded models?
That's the main reason the cascade happens in Django and not in the database.

Akash Sen

unread,
May 14, 2023, 4:31:34 AM5/14/23
to Django developers (Contributions to Django itself)
No it will not trigger the delete signals. The point is to delete an object with O(1) database queries instead of O(n), Have to add another warning message if the signals are being used with DB level cascading.

jatin singh

unread,
May 14, 2023, 9:38:21 AM5/14/23
to django-d...@googlegroups.com
signals ?..

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fef26391-c9ec-49d6-9ce9-a1d4fc52b1a3n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages