You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DataJoint needs an effective way of specifying a subset of the data from the database for export, deletion, publishing, backups, synchronization, and sharing.
dj.Diagram objects already provide powerful ways of specifying a specific subset of tables through their set operators: union, difference, intersection, etc. Adding the ability to restrict the data in the tables of a diagram would complete the functionality necessary for specifying a cross-section of the data in the database.
Requirements
dj.Diagram must provide a way to apply a restriction to any of its tables.
Restrictions must propagate down through dependencies and up from part to master when necessary.
If a restriction causes a table to become empty, the table is excluded from the diagram.
Justification
Specifying a subset of the data in the database across multiple tables and schemas is a basic functionality that would allow many other operations. Deletions and backups are prime examples.
Alternative Considerations
The cascading delete feature already allows deleting a cross-section of the data based on a restricted table.
We have a design for this feature that also addresses #1110 (cascade delete fails on MySQL 8). See PR #1407 and docs/design/restricted-diagram.md for the full design.
Two restriction operators
dj.Diagram gains two distinct operators for applying restrictions to nodes, with different semantics at convergence points (where a child has multiple restricted ancestors):
diagram.cascade(expr) — OR at convergence, downstream only.
# Delete subject 1's data and everything depending on itrd=dj.Diagram(schema).cascade(Session&'subject_id=1')
rd.preview() # show affected tables and row countsrd.delete() # reverse topo order, leaves first
At convergence, restrictions combine with OR: if any restricted ancestor taints a row, it's included. Non-downstream tables are excluded.
diagram.restrict(expr) — AND at convergence, includes upstream context.
# Export subject 1's visual stimulus recordingsrd= (dj.Diagram(schema)
.restrict(Session&'subject_id=1')
.restrict(Stimulus&'type="visual"'))
rd.preview() # show selected cross-sectionrd.export(path) # includes upstream referential context
At convergence, restrictions combine with AND: a row must satisfy all restricted ancestors. Non-downstream tables remain for referential integrity.
Additional operations
diagram.drop() — shared traversal infrastructure, no restrictions (DDL)
diagram.preview() — inspect affected data before executing
diagram.draw() — visualize with restricted nodes highlighted
Restriction propagation
Both operators propagate restrictions downstream through FK edges using the attr_map stored in the dependency graph. Aliased FKs (same parent, multiple FK paths) always combine with OR regardless of operator.
part_integrity becomes a parameter on cascade(): during propagation, the diagram can enforce, ignore, or cascade restrictions upward from part to master — as a pre-check before any operation executes.
Activity
guzman-raphael commentedon Jan 28, 2021
From separate Slack discussions, a possible syntax was presented as:
section = dj.Diagram(schema) & (Session & 'subject=1')drewyangdev commentedon Mar 14, 2025
This issue is closed because there has been no activity for more than 365 days, please reopen if it's still applicable.
3 remaining items
[-]Applying Restrictions to a Diagram[/-][+]FEAT: Applying Restrictions to a Diagram[/+]github-actions commentedon Oct 3, 2025
This issue is stale because it has been open for 45 days with no activity.
github-actions commentedon Feb 9, 2026
This issue is stale because it has been open for 45 days with no activity.
docs: design for restricted diagrams (#865, #1110)
dimitri-yatsenko commentedon Feb 21, 2026
Design: Restricted Diagrams
We have a design for this feature that also addresses #1110 (cascade delete fails on MySQL 8). See PR #1407 and
docs/design/restricted-diagram.mdfor the full design.Two restriction operators
dj.Diagramgains two distinct operators for applying restrictions to nodes, with different semantics at convergence points (where a child has multiple restricted ancestors):diagram.cascade(expr)— OR at convergence, downstream only.At convergence, restrictions combine with OR: if any restricted ancestor taints a row, it's included. Non-downstream tables are excluded.
diagram.restrict(expr)— AND at convergence, includes upstream context.At convergence, restrictions combine with AND: a row must satisfy all restricted ancestors. Non-downstream tables remain for referential integrity.
Additional operations
diagram.drop()— shared traversal infrastructure, no restrictions (DDL)diagram.preview()— inspect affected data before executingdiagram.draw()— visualize with restricted nodes highlightedRestriction propagation
Both operators propagate restrictions downstream through FK edges using the
attr_mapstored in the dependency graph. Aliased FKs (same parent, multiple FK paths) always combine with OR regardless of operator.part_integritybecomes a parameter oncascade(): during propagation, the diagram can enforce, ignore, or cascade restrictions upward from part to master — as a pre-check before any operation executes.feat: implement graph-driven cascade delete and restrict on Diagram