#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.