From 06d9913cebc61cb28a268fb197211fe0882f8de6 Mon Sep 17 00:00:00 2001 From: jbirddog <100367399+jbirddog@users.noreply.github.com> Date: Tue, 3 Jan 2023 22:07:41 -0500 Subject: [PATCH] Helper function to support reaping process instances (#91) --- .../delete_process_instances_with_criteria.py | 63 +++++++++++++++++++ .../services/process_instance_processor.py | 1 + 2 files changed, 64 insertions(+) create mode 100644 spiffworkflow-backend/src/spiffworkflow_backend/scripts/delete_process_instances_with_criteria.py diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/scripts/delete_process_instances_with_criteria.py b/spiffworkflow-backend/src/spiffworkflow_backend/scripts/delete_process_instances_with_criteria.py new file mode 100644 index 00000000..5b422525 --- /dev/null +++ b/spiffworkflow-backend/src/spiffworkflow_backend/scripts/delete_process_instances_with_criteria.py @@ -0,0 +1,63 @@ +"""Delete_process_instances_with_criteria.""" +from time import time +from typing import Any + +from flask_bpmn.models.db import db +from sqlalchemy import or_ + +from spiffworkflow_backend.models.process_instance import ProcessInstanceModel +from spiffworkflow_backend.models.script_attributes_context import ( + ScriptAttributesContext, +) +from spiffworkflow_backend.models.spiff_step_details import SpiffStepDetailsModel +from spiffworkflow_backend.scripts.script import Script + + +class DeleteProcessInstancesWithCriteria(Script): + """DeleteProcessInstancesWithCriteria.""" + + def get_description(self) -> str: + """Get_description.""" + return "Delete process instances that match the provided criteria," + + def run( + self, + script_attributes_context: ScriptAttributesContext, + *args: Any, + **kwargs: Any, + ) -> Any: + """Run.""" + criteria_list = args[0] + + delete_criteria = [] + delete_time = time() + + for criteria in criteria_list: + delete_criteria.append( + (ProcessInstanceModel.process_model_identifier == criteria["name"]) + & ProcessInstanceModel.status.in_(criteria["status"]) # type: ignore + & ( + ProcessInstanceModel.updated_at_in_seconds + < (delete_time - criteria["last_updated_delta"]) + ) + ) + + results = ( + ProcessInstanceModel.query.filter(or_(*delete_criteria)).limit(100).all() + ) + rows_affected = len(results) + + if rows_affected > 0: + ids_to_delete = list(map(lambda r: r.id, results)) # type: ignore + + step_details = SpiffStepDetailsModel.query.filter( + SpiffStepDetailsModel.process_instance_id.in_(ids_to_delete) # type: ignore + ).all() + + for deletion in step_details: + db.session.delete(deletion) + for deletion in results: + db.session.delete(deletion) + db.session.commit() + + return rows_affected diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py index 74e4ab24..4a4f99a4 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py @@ -157,6 +157,7 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore "_strptime": _strptime, "enumerate": enumerate, "list": list, + "map": map, } # This will overwrite the standard builtins