From: Mike Bayer Date: Wed, 22 Nov 2023 15:58:00 +0000 (-0500) Subject: re-add cascade caveats X-Git-Tag: rel_2_0_24~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e8362d2b9f7aa331ccebbb882d7234edf22a080;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git re-add cascade caveats these got removed and never restored in 2.0 References: https://github.com/sqlalchemy/sqlalchemy/discussions/10672 Change-Id: Ibbd9a8ab04556ebd581f9287b54fe1ffdaacee79 (cherry picked from commit 4279e715e0b4af819a0434daa5bf9e0c18789bec) --- diff --git a/doc/build/orm/cascades.rst b/doc/build/orm/cascades.rst index 02d68669ee..efb997560a 100644 --- a/doc/build/orm/cascades.rst +++ b/doc/build/orm/cascades.rst @@ -301,6 +301,14 @@ The feature by default works completely independently of database-configured In order to integrate more efficiently with this configuration, additional directives described at :ref:`passive_deletes` should be used. +.. warning:: Note that the ORM's "delete" and "delete-cascade" behavior applies + **only** to the use of the :meth:`_orm.Session.delete` method to mark + individual ORM instances for deletion within the :term:`unit-of-work` process. + It does **not** apply to "bulk" deletes, which would be emitted using + the :func:`_sql.delete` construct as illustrated at + :ref:`orm_queryguide_update_delete_where`. See + :ref:`orm_queryguide_update_delete_caveats` for additional background. + .. seealso:: :ref:`passive_deletes` diff --git a/doc/build/orm/queryguide/dml.rst b/doc/build/orm/queryguide/dml.rst index 967397f1ae..67614ac92c 100644 --- a/doc/build/orm/queryguide/dml.rst +++ b/doc/build/orm/queryguide/dml.rst @@ -993,6 +993,52 @@ For a DELETE, an example of deleting rows based on criteria:: >>> session.connection() BEGIN (implicit)... +.. warning:: Please read the following section :ref:`orm_queryguide_update_delete_caveats` + for important notes regarding how the functionality of ORM-Enabled UPDATE and DELETE + diverges from that of ORM :term:`unit-of-work` features, such + as using the :meth:`_orm.Session.delete` method to delete individual objects. + + +.. _orm_queryguide_update_delete_caveats: + +Important Notes and Caveats for ORM-Enabled Update and Delete +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ORM-enabled UPDATE and DELETE features bypass ORM :term:`unit-of-work` +automation in favor being able to emit a single UPDATE or DELETE statement +that matches multiple rows at once without complexity. + +* The operations do not offer in-Python cascading of relationships - it is + assumed that ON UPDATE CASCADE and/or ON DELETE CASCADE is configured for any + foreign key references which require it, otherwise the database may emit an + integrity violation if foreign key references are being enforced. See the + notes at :ref:`passive_deletes` for some examples. + +* After the UPDATE or DELETE, dependent objects in the :class:`.Session` which + were impacted by an ON UPDATE CASCADE or ON DELETE CASCADE on related tables, + particularly objects that refer to rows that have now been deleted, may still + reference those objects. This issue is resolved once the :class:`.Session` + is expired, which normally occurs upon :meth:`.Session.commit` or can be + forced by using :meth:`.Session.expire_all`. + +* ORM-enabled UPDATEs and DELETEs do not handle joined table inheritance + automatically. See the section :ref:`orm_queryguide_update_delete_joined_inh` + for notes on how to work with joined-inheritance mappings. + +* The WHERE criteria needed in order to limit the polymorphic identity to + specific subclasses for single-table-inheritance mappings **is included + automatically** . This only applies to a subclass mapper that has no table of + its own. + +* The :func:`_orm.with_loader_criteria` option **is supported** by ORM + update and delete operations; criteria here will be added to that of the UPDATE + or DELETE statement being emitted, as well as taken into account during the + "synchronize" process. + +* In order to intercept ORM-enabled UPDATE and DELETE operations with event + handlers, use the :meth:`_orm.SessionEvents.do_orm_execute` event. + + .. _orm_queryguide_update_delete_sync: