datajoint-python
datajoint-python copied to clipboard
Master rows not deleted when corresponding Parts are deleted via dependency
trafficstars
Bug Report
Description
When Part table rows are deleted because an upstream dependency is deleted, the master rows with key prefix for those rows should also be deleted. They are not, and this causes data integrity violation:
- Downstream tables depending on those part table rows transitively through the master table will not be deleted.
- Repopulating the master table will not recalculate the deleted rows.
Reproducibility
Include:
- OS: Linux (Ubuntu 18.04)
- Python Version 3.8.10
- MySQL Version: 5.7
- MySQL Deployment Strategy: local docker and Google Cloud Sql
- DataJoint Version: 0.13.2
- Minimum number of steps to reliably reproduce the issue: See below
- Complete error stack as a result of evaluating the above steps: See below
Reproducer: The SegmentRound row is properly deleted when corresponding AcquisitionRound row is deleted. However, the corresponding Segment row is NOT deleted, but should be.
import datajoint as dj
schema = dj.schema("bad_dep")
@schema
class Acquisition(dj.Manual):
definition = """
id: int
"""
@schema
class AcquisitionRound(dj.Manual):
definition = """
-> Acquisition
round: int
"""
@schema
class Segment(dj.Computed):
definition = """
-> Acquisition
"""
class SegmentRound(dj.Part): # Only depends on one round per image
definition = """
-> Segment
-> AcquisitionRound
"""
def make(self, key):
segment_round = 1 # may depend on acquisition
self.insert1(key)
self.SegmentRound.insert1({**key, "round": segment_round})
Acquisition.insert1({'id': 1})
AcquisitionRound.insert([{'id': 1, 'round': r} for r in range(2)])
Segment.populate()
assert len(Segment.SegmentRound()) == 1
assert len(Segment()) == 1
AcquisitionRound.delete(safemode=False)
assert len(Segment.SegmentRound()) == 0
assert len(Segment()) == 0 # FAILS
Deleting 1 rows from `bad_dep`.`__segment__segment_round`
Deleting 2 rows from `bad_dep`.`acquisition_round`
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-2-ab560ec702b8> in <module>
42
43 assert len(Segment.SegmentRound()) == 0
---> 44 assert len(Segment()) == 0 # FAILS
AssertionError:
Expected Behavior
The final assertion should not fail.