Skip to content

Commit aedd820

Browse files
docs(diagram): document restrict is downstream-only; no part->master walk-up
Make explicit (docstring + inline comment) that Diagram.restrict never walks upward from a Part to its Master — that walk is exclusive to cascade delete, which must be compositionally atomic under mutation. restrict is a read-only, seed-at-roots, downstream-only export: a Master is always included with its Parts before its Parts, so no Part FK dangles; use trace for upstream/ancestor closure. No behavior change (the mode==cascade guard already enforced this); the comment guards against accidentally enabling it for restrict later.
1 parent 29ce695 commit aedd820

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

src/datajoint/diagram.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,13 @@ def restrict(self, table_expr):
663663
664664
Cannot be called on a Diagram produced by ``Diagram.cascade()``.
665665
666+
Propagation is strictly downstream. Unlike ``cascade``'s
667+
``part_integrity="cascade"``, ``restrict`` never walks upward from a
668+
Part to its Master: an export is seeded at root entities and flows
669+
down, so a Master (with all of its Parts) is always included before
670+
its Parts and no Part foreign key dangles. Use :meth:`trace` for
671+
upstream / ancestor closure.
672+
666673
Parameters
667674
----------
668675
table_expr : QueryExpression
@@ -796,6 +803,14 @@ def _propagate_restrictions(self, start_node, mode, part_integrity="enforce"):
796803
# which assumed shared PK attribute names. See #1429.
797804
# Deduped per (part, master) pair — every restricted Part
798805
# of a master contributes its own master rows.
806+
#
807+
# This upward walk is intentionally exclusive to cascade
808+
# delete. `restrict` (mode="restrict") is downstream-only by
809+
# design: export is seeded at roots and flows down, so a
810+
# Master is always included (with all its Parts) before its
811+
# Parts and no Part FK dangles — a read-only slice has no
812+
# compositional-atomicity obligation. Do not enable this for
813+
# restrict.
799814
if part_integrity == "cascade" and mode == "cascade":
800815
master_name = extract_master(target)
801816
if (

0 commit comments

Comments
 (0)