-
Notifications
You must be signed in to change notification settings - Fork 36
Refactor and refine cascade deletion rules #2806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: production
Are you sure you want to change the base?
Conversation
This was originally in commit 56cb36f, but is being moved here as this is more fitting for the functionality and easier to find in the future
specifyweb/specify/build_models.py
Outdated
@@ -112,11 +96,13 @@ def make_relationship(modelname, rel, datamodel): | |||
return None | |||
|
|||
try: | |||
on_delete = SPECIAL_DELETION_RULES["%s.%s" % (modelname.capitalize(), rel.name.lower())] | |||
on_delete = SPECIAL_DELETION_RULES[f"{rel.name.capitalize()}"][f"{modelname.lower()}"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you swapped the relationship and model name. Is this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I should change the variable names...
This was confusing even in production.
Take this for example.
'Agent.specifyuser': models.SET_NULL, |
This operates as "When a Specifyuser is deleted, set its relationship with Agent to null"
Where the on_delete functionality for these rules get defined, the
modelname
would be Agent, and rel.name
would be specifyuser
.specify7/specifyweb/specify/build_models.py
Line 115 in 741a5e3
on_delete = SPECIAL_DELETION_RULES["%s.%s" % (modelname.capitalize(), rel.name.lower())] |
I thought it might make more sense to have the table being deleted be the 'primary' key of the dictonary, so I changed it to 'Specifyuser' : {'agent': models.SET_NULL}
As a result of this flip, I flipped the variables where on_delete
was being defined to ensure the same functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change it to 'Agent': {'specifyuser': models.SET_NULL}
if that makes more sense. It just didn't read as I would expect it to.
Even now, I'm second guessing my changes because of how everything is worded (even though I have tested it many times)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think adding an example breakdown you provided here as a comment on top of SPECIAL_DELETION_RULES
(in addition to what you already have there) would be great
Add a block for
|
For more context, this is regarding adding a deletion blocker to SpecifyUser. |
specify7/specifyweb/specify/load_datamodel.py Lines 222 to 231 in 4877f75
We could manually use SQL to get the correct information, but that will only be a short-term solution (which may be fine for now). Preferably, we would want to engineer a way to load/register these Specify 7 specific tables in the internal specify datamodel. (If such a way already exists and I am overlooking it, then feel free to point it out. I have checked all attributes on specify.models and spdataset does not exist) |
Additionally requested by @grantfitzsimmons: |
I have went through and cleaned up all of the deletion rules as they stand, so this is ready for testing. Adding reverse-relationship deletion blockers (i.e. the relationship we want to protect does not exist on the table we want to delete) will require a little more engineering and time: there is no reason to further delay the changes that have already been made on this branch. These deletion rules can probably be addressed/changed when #2847 and #2813 are being developed (once those two issues are being developed, #2584 can be fixed as well), but this branch should probably be merged before work on those issues begin. Also, along with testing #2511, can issues #1385, #1431, #88, and #150 additionally be tested to see if they still occur? If so, the fixes for those can be added in this PR. |
Additionally remove lines from agent_rules.py which were used for testing, and should not have gotten pushed to origin!
After deletion: Looks good! ✅
Deleted correctly! ✅
https://ptrm11923-issue-1694.test.specifysystems.org/specify/view/spauditlog/2165/ Trying to delete a
✅
✅ |
It looks like #1385 is not solved
|
Does not solve #1431 either
|
#2511 is not solved either
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please let me know if everything I discovered is intentional. I can formally aprove once I hear from you again
Turns out the models contain the attribute name as plural, to signify this is a to-many relationship. For deletion rules, the table name is needed and NOT the name of the attribute on the base_table model
These remaining issues should be fixed now.
Some concerns: Correctly solving this issue would be impossible with the current way the backend sets up its deletion rules (There is no There is another concerning side-effect with this issue (currently in production). When Borrow is deleted, it tries to cascade and delete its associated Addressofrecord. If there are multiple records referencing the Addressofrecord, the error is thrown. However, if the Borrow is the only record referencing the Addressofrecord, both the Addressofrecord and Borrow will be deleted.
Interactions are flagged as dependents of Addressofrecord (i.e., they require an Addressofrecord), but at a database level they do not require an Addressofrecord (similar to #2299). Spprincipal and Specifyuser have a many-to-many relationship: a relationship type which is not created/supported on the backend. We would either need a proper implementation to handle creating Django many-to-many relationships (the on delete behavior would have to be handled differently than other fields) or use SQL directly to handle deletion rules on a case-by-case basis. To maintain compatibility with Specify 6, I will not touch the schema mapping fields in this pull request. This can be addressed again when the frontend gets a 'proper' implementation of schema mappings. |
@melton-jason I need to take a look at this again.
I would remove that requirement– that's bizarre. What do you think @maxpatiiuk? |
I believe address of record is marked as dependent so that it can be displayed as a sub view on the form (otherwise it would only be available as a query combo box and all existing forms would have to be redone) |
Fixing #114 would allow for editing independent resources in sub-views |
@melton-jason Is this something that just needs to be tested? |
Yes, testing can probably be done on this. There are still 2 cases I need further clarification/discussion on.
It has been awhile, so I would need to look into this specific issue again. Should deleting the interaction try and delete its address of record? I would immediately say no, because the address of record can be referenced by other interactions (or tables), hence the issue that caused #2511. (#1431)
We need to identify what really needs to be done and what the issue is here. I would lean more towards this being a frontend issue with -to-many relationships. The issue is caused because a Preparation is removed from the Collection Object form, but that Preparation references a Loan Preparation, which causes the error to be thrown. @grantfitzsimmons For that view, I envision making any -to-many relationship like this display the warning symbol next to the trash can, which displays that resource's deletion blockers when clicked and prevents the deletion |
I'm going to request both UX and Dev Testing on this PR to conform with our new policy on needing 3 Reviews, Consisting of both Devs and UX people. |
Triggered by 7d3ccca on branch refs/heads/issue-1694
There were changes to the delete blocker dialog and the corresponding backend endpoint in To test this fix:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#1385 could not reproduce error on edge
with https://fwri2023-edge.test.specifysystems.org/specify/query/48/
- Deletes preparation linked to interaction without error!
- When I clicked Save for the loan, a new tab opened with this: ReportException at report_runner_run.pdf. Is this related or a separate issue?
1431.mov
#2511 not fixed
Specify 7 Crash Report - 2024-01-29T21_16_00.444Z.txt
https://herbrbge71423-issue1694.test.specifysystems.org/specify/view/borrow/1364/
#2806 (comment) looks good!
Fixes #1694, #2784, #1069
Additionally test #2511 to see if the error still occurs. If so, we can easily add AddressofRecord to Borrow deletion blockers.
In addition to refactoring the code, the following rules were added:
While deleting any of the following:
In addition, we now have the ability to extend deletion blockers as we see fit on the backend.
Added: