#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 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:16>
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.6e19137219f9e4029215b0eedba7db3a%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to