Implement graph-driven cascade delete and restrict on Diagram#1407
Open
dimitri-yatsenko wants to merge 8 commits intomasterfrom
Open
Implement graph-driven cascade delete and restrict on Diagram#1407dimitri-yatsenko wants to merge 8 commits intomasterfrom
dimitri-yatsenko wants to merge 8 commits intomasterfrom
Conversation
- Unrestricted nodes are not affected by operations - Multiple restrict() calls create separate restriction sets - Delete combines sets with OR (any taint → delete) - Export combines sets with AND (all criteria → include) - Within a set, multiple FK paths combine with OR (structural) - Added open questions on lenient vs strict AND and same-table restrictions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Delete: one restriction, propagated downstream only, OR at convergence - Export: downstream + upstream context, AND at convergence - Removed over-engineered "multiple restriction sets" abstraction - Clarified alias nodes (same parent, multiple FKs) vs convergence (different parents) - Non-downstream tables: excluded for delete, included for export Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- cascade(): OR at convergence, downstream only — for delete - restrict(): AND at convergence, includes upstream context — for export - Both propagate downstream via attr_map, differ only at convergence - Table.delete() internally constructs diagram.cascade() - part_integrity is a parameter of cascade(), not delete() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Table.drop() rewritten as Diagram(table).drop() - Shared infrastructure: reverse topo traversal, part_integrity pre-checks, unloaded-schema error handling, preview - drop is DDL (no restrictions), delete is DML (with cascade restrictions) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Feb 21, 2026
Replace the error-driven cascade in Table.delete() (~200 lines) with graph-driven restriction propagation on Diagram. Table.delete() and Table.drop() now delegate to Diagram.cascade().delete() and Diagram.drop() respectively. New Diagram methods: - cascade(table_expr) — OR at convergence, one-shot, for delete - restrict(table_expr) — AND at convergence, chainable, for export - delete() — execute cascade delete in reverse topo order - drop() — drop tables in reverse topo order - preview() — show affected tables and row counts - _from_table() — lightweight factory for Table.delete/drop Restructure: single Diagram(nx.DiGraph) class always defined. Only visualization methods gated on diagram_active. Resolves #865, #1110. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflicts in diagram.py and table.py: - Adopt master's config access pattern (self._connection._config) - Keep graph-driven cascade/restrict implementation - Apply master's declare() config param, split_full_table_name(), _config in store context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add assert after conditional config import to narrow type for mypy (filepath.py, attach.py) - Add Any type annotation to untyped config parameters (hash_registry.py) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replace the error-driven cascade in
Table.delete()(~200 lines) with graph-driven restriction propagation onDiagram.Table.delete()andTable.drop()now delegate toDiagram.cascade().delete()andDiagram.drop()respectively.Resolves: #865 (applying restrictions to a Diagram), #1110 (cascade delete fails on MySQL 8 with limited privileges)
New
Diagrammethodscascade(table_expr)— OR at convergence, one-shot, for deleterestrict(table_expr)— AND at convergence, chainable, for exportdelete()— execute cascade delete in reverse topo orderdrop()— drop tables in reverse topo orderpreview()— show affected tables and row counts without modifying data_from_table()— lightweight internal factory forTable.delete/Table.dropArchitecture changes
Diagramclass: Removed theif diagram_active:conditional.Diagram(nx.DiGraph)is always defined. Only visualization methods (draw,make_dot,make_svg, etc.) are gated ondiagram_active.Table.delete()rewritten: ~200 lines → ~10 lines delegating toDiagramTable.drop()rewritten: ~35 lines → ~10 lines delegating toDiagrampart_integrity: Moved from post-hoc check after delete to pre-check during diagram constructionRestriction propagation rules
For edge Parent→Child with
attr_map:parent_attrs ⊆ child.primary_keyfk_attrs ≠ pk_attrs)parent.proj(**{fk: pk for fk, pk in attr_map.items()})parent_attrs ⊄ child.primary_keyparent.proj()Advantages over previous implementation
part_integritypreview()shows affected data before executingFiles changed
src/datajoint/diagram.pyDiagramclass withcascade(),restrict(),_propagate_restrictions(),delete(),drop(),preview(),_from_table()src/datajoint/table.pyTable.delete()andTable.drop()rewritten to delegate toDiagram. Dead cascade code removedsrc/datajoint/user_tables.pyPart.drop()passespart_integritythroughdocs/design/restricted-diagram-spec.mdTest plan
test_cascading_delete.pytests passtest_cascade_delete.pytests pass (3 MySQL + 3 PostgreSQL)test_erd.pytests passtest_diagram_operations.pyfor new diagram-level cascade/restrict testsSee
docs/design/restricted-diagram-spec.mdfor the full implementation spec.🤖 Generated with Claude Code