Auto-commit local changes before build (2026-01-13 14:27:23) #112
@ -1 +1 @@
|
|||||||
v20260113-06-overrides-error-match-modes
|
v20260113-07-job-delete-fix
|
||||||
|
|||||||
@ -423,25 +423,17 @@ def job_delete(job_id: int):
|
|||||||
job = Job.query.get_or_404(job_id)
|
job = Job.query.get_or_404(job_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Collect run ids for FK cleanup in auxiliary tables that may not have ON DELETE CASCADE
|
# Collect run IDs up-front for cleanup across dependent tables
|
||||||
run_ids = []
|
run_ids = [r.id for r in JobRun.query.filter_by(job_id=job.id).all()]
|
||||||
mail_message_ids = []
|
|
||||||
|
|
||||||
for run in job.runs:
|
# Put any related mails back into the inbox and unlink from job
|
||||||
if run.id is not None:
|
msgs = MailMessage.query.filter(MailMessage.job_id == job.id).all()
|
||||||
run_ids.append(run.id)
|
for msg in msgs:
|
||||||
if run.mail_message_id:
|
if hasattr(msg, "location"):
|
||||||
mail_message_ids.append(run.mail_message_id)
|
msg.location = "inbox"
|
||||||
|
msg.job_id = None
|
||||||
|
|
||||||
# Put related mails back into the inbox and unlink from job
|
# Clean up tables that may not have ON DELETE CASCADE in older schemas.
|
||||||
if mail_message_ids:
|
|
||||||
msgs = MailMessage.query.filter(MailMessage.id.in_(mail_message_ids)).all()
|
|
||||||
for msg in msgs:
|
|
||||||
if hasattr(msg, "location"):
|
|
||||||
msg.location = "inbox"
|
|
||||||
msg.job_id = None
|
|
||||||
|
|
||||||
# Ensure run_object_links doesn't block job_runs deletion (older schemas may miss ON DELETE CASCADE)
|
|
||||||
if run_ids:
|
if run_ids:
|
||||||
db.session.execute(
|
db.session.execute(
|
||||||
text("DELETE FROM run_object_links WHERE run_id IN :run_ids").bindparams(
|
text("DELETE FROM run_object_links WHERE run_id IN :run_ids").bindparams(
|
||||||
@ -449,13 +441,47 @@ def job_delete(job_id: int):
|
|||||||
),
|
),
|
||||||
{"run_ids": run_ids},
|
{"run_ids": run_ids},
|
||||||
)
|
)
|
||||||
|
db.session.execute(
|
||||||
|
text("DELETE FROM job_run_review_events WHERE run_id IN :run_ids").bindparams(
|
||||||
|
bindparam("run_ids", expanding=True)
|
||||||
|
),
|
||||||
|
{"run_ids": run_ids},
|
||||||
|
)
|
||||||
|
db.session.execute(
|
||||||
|
text("DELETE FROM ticket_job_runs WHERE job_run_id IN :run_ids").bindparams(
|
||||||
|
bindparam("run_ids", expanding=True)
|
||||||
|
),
|
||||||
|
{"run_ids": run_ids},
|
||||||
|
)
|
||||||
|
db.session.execute(
|
||||||
|
text("DELETE FROM remark_job_runs WHERE job_run_id IN :run_ids").bindparams(
|
||||||
|
bindparam("run_ids", expanding=True)
|
||||||
|
),
|
||||||
|
{"run_ids": run_ids},
|
||||||
|
)
|
||||||
|
db.session.execute(
|
||||||
|
text("DELETE FROM job_objects WHERE job_run_id IN :run_ids").bindparams(
|
||||||
|
bindparam("run_ids", expanding=True)
|
||||||
|
),
|
||||||
|
{"run_ids": run_ids},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Overrides scoped to this job (object overrides)
|
||||||
|
db.session.execute(text("UPDATE overrides SET job_id = NULL WHERE job_id = :job_id"), {"job_id": job.id})
|
||||||
|
|
||||||
|
# Ticket/Remark scopes may reference a specific job
|
||||||
|
db.session.execute(text("UPDATE ticket_scopes SET job_id = NULL WHERE job_id = :job_id"), {"job_id": job.id})
|
||||||
|
db.session.execute(text("UPDATE remark_scopes SET job_id = NULL WHERE job_id = :job_id"), {"job_id": job.id})
|
||||||
|
|
||||||
# Ensure job_object_links doesn't block jobs deletion (older schemas may miss ON DELETE CASCADE)
|
# Ensure job_object_links doesn't block jobs deletion (older schemas may miss ON DELETE CASCADE)
|
||||||
if job.id is not None:
|
db.session.execute(
|
||||||
db.session.execute(
|
text("DELETE FROM job_object_links WHERE job_id = :job_id"),
|
||||||
text("DELETE FROM job_object_links WHERE job_id = :job_id"),
|
{"job_id": job.id},
|
||||||
{"job_id": job.id},
|
)
|
||||||
)
|
|
||||||
|
# Finally remove runs and the job itself
|
||||||
|
if run_ids:
|
||||||
|
db.session.execute(text("DELETE FROM job_runs WHERE job_id = :job_id"), {"job_id": job.id})
|
||||||
|
|
||||||
db.session.delete(job)
|
db.session.delete(job)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
@ -465,4 +491,4 @@ def job_delete(job_id: int):
|
|||||||
print(f"[jobs] Failed to delete job: {exc}")
|
print(f"[jobs] Failed to delete job: {exc}")
|
||||||
flash("Failed to delete job.", "danger")
|
flash("Failed to delete job.", "danger")
|
||||||
|
|
||||||
return redirect(url_for("main.jobs"))
|
return redirect(url_for("main.jobs"))
|
||||||
|
|||||||
@ -43,6 +43,14 @@
|
|||||||
- Extended overrides UI with a match type selector and improved edit support for existing overrides
|
- Extended overrides UI with a match type selector and improved edit support for existing overrides
|
||||||
- Added database migration to create and backfill overrides.match_error_mode for existing records
|
- Added database migration to create and backfill overrides.match_error_mode for existing records
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v20260113-07-job-delete-fix
|
||||||
|
|
||||||
|
- Fixed an error that occurred when deleting a job.
|
||||||
|
- Corrected backend deletion logic to prevent exceptions during job removal.
|
||||||
|
- Ensured related records are handled safely to avoid constraint or reference errors.
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
## v0.1.20
|
## v0.1.20
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user