#21961: Add support for database-level cascading options
-------------------------------------+-------------------------------------
     Reporter:  Christophe Pettus    |                    Owner:  Nick
                                     |  Stefan
         Type:  New feature          |                   Status:  assigned
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Nick Stefan):

 Hi Dylan.

 I think your thoughts do make logical sense in response to Carl. However,
 that proposal was written a long time ago (it was circa 2014). I think
 most of that "ambiguity"  discussed then comes from 2014 DBs not
 supporting ON DELETE CASCADE. That lack of support then required the need
 to have automatic fall backs.

 In 2017, all of the supported databases should support ON DELETE CASCADE,
 so a single on_delete kwarg still makes sense to me.

 I guess there is "ambiguity" regarding signals etc, but I don't think that
 should be the case. DO_NOTHING has been a value for a long time.
 DB_CASCADE is really just DO_NOTHING plus some more SQL, so it should be
 understood that there can't be signals.

 Of course, that's just my opinion, and I admit that it might be unpopular
 based on how my PR has fared lol :).

 I opened a PR back in the summer proving the concept, and added pre check
 tests to prevent hairy situations like generic foreign keys, concrete
 model inheritance, etc: https://github.com/django/django/pull/8661 .

 --Nick

 Replying to [comment:16 Dylan Young]:
 > A separate kwarg (`on_delete_db`) is a much better proposal:
 >
 > 1) It (together with adequate documentation) eliminates *ALL* of the
 ambiguities present in the current proposal.
 > 2) When this kwarg is unspecified, it should default to the value of
 `on_delete`, ensuring as closely as possible consistency between raw
 database operations and Django operations.
 > 3) Otherwise it leaves granular control up to the user: Don't need
 delete signals (postgres should be able to support post_delete, no?)? Use
 the configuration outlined by Carl.  Need delete signals in your Django
 application, but still want sane deletion behaviour in other applications
 using your DB? Simply set `on_delete`.  Need your other applications to
 have different deletion behaviour? Just reverse the configuration outlined
 by Carl... Or any number of options?
 > 4) You could add some special flags that isolate the ORM-level deletion
 to specific DB-problematic cases (Generic Foreign Keys, Inheritance...),
 thus eliminating the overhead of python-space constraints in the majority
 of cases.
 > 5) Maybe it also makes testing Django's ORM on_delete behaviour easier?
 By adding the ability to easily cross-reference with the Database's
 internal implementation... could be wrong on that, but with `on_delete`
 set to cascade, you would expect the final deletion call of the original
 object (after all the ORM work to delete related objects) to only delete a
 single instance right? If it deletes more than expected, the error in the
 ORMs deletion emulation is exposed.
 >
 > An extra thought on Postgres:
 >
 > It seems like it should be possible to support signals with DB-level
 constraints.  Actually any DB that supports `returning` + transactions
 should be capable, no?
 >
 >
 > Replying to [comment:9 Carl Meyer]:
 > > I think we should consider introducing this feature as a totally
 separate kwarg (`on_delete_db`) rather than conflating it with the
 existing Python-level `on_delete`. The various edge cases and implicit
 fallbacks in the existing proposal worry me, and I think it would be
 better to be more explicit and clear about what is happening on the
 database level vs the Python level.
 > >
 > > Right now the contract of `on_delete` is very simple: it takes a
 Python callable which will be called when a delete cascades. There is
 nothing at all special about the built-in callables, they are just
 conveniences for common cases. The current API proposal complicates that
 contract dramatically: now you have an `on_delete` kwarg which sometimes
 accepts Python callables but can also accept magical constants which do
 something entirely different (and also have an implicit fallback
 relationship with one of the built-in callables).
 > >
 > > So under my proposal, if you want database-level cascade, you would
 specify `on_delete=models.DO_NOTHING, on_delete_db=models.DB_CASCADE` or
 similar. Sure this is a bit more verbose, but I think that's worth it for
 the gains in clarity and simplicity.
 > >
 > > For similar reasons, I feel pretty strongly that we should NOT
 automatically fallback from db-cascade to non-db-cascade depending on the
 backend capabilities. It introduces too many differences in behavior
 depending on db backend. Trying to claim to provide cross-db portability
 when we can't really do so consistently is worse than simply not claiming
 to provide it at all. DB-level cascade (like many other "advanced" db-
 level features) is something you should only take advantage of when you
 know your code will be running on a database that supports it, full stop.
 Use of `on_delete_db` on a backend that can't support it should be an
 error.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/21961#comment:17>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/061.4b8b7999afe3f05ee5690c286e00fab4%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to