From 43e6053c6de2a52e1e2d67ae22d211ce95add132 Mon Sep 17 00:00:00 2001 From: TheNoxium Date: Tue, 28 Oct 2025 15:07:26 +0500 Subject: [PATCH] fix: deletion requests --- api/api/db/logic/ps_node.py | 74 +++++++++++++++---------------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/api/api/db/logic/ps_node.py b/api/api/db/logic/ps_node.py index 3ef2e8e..ad7389c 100644 --- a/api/api/db/logic/ps_node.py +++ b/api/api/db/logic/ps_node.py @@ -129,66 +129,52 @@ async def get_nodes_for_deletion_ordered(connection: AsyncConnection, node_id: i return ordered_node_ids -async def delete_ps_node_by_id_CASCADE(connection: AsyncConnection, node_id: int) -> tuple[bool, str]: - """ - Полностью удаляет узел из базы данных по ID - ON DELETE CASCADE. - """ - try: - node_query = select(ps_node_table).where(ps_node_table.c.id == node_id) - node_result = await connection.execute(node_query) - node_data = node_result.mappings().first() - - if not node_data: - return False, "Node not found" - - ps_id = node_data["ps_id"] - - await remove_node_from_process_schema_settings(connection, ps_id, node_id) - - result = await connection.execute(delete(ps_node_table).where(ps_node_table.c.id == node_id)) - - if result.rowcount > 0: - await connection.commit() - return True, "Success" - else: - await connection.rollback() - return False, "Node not found" - - except Exception as e: - await connection.rollback() - return False, str(e) - - async def delete_ps_nodes_delete_handler(connection: AsyncConnection, node_ids: List[int]) -> List[int]: """ - Поочередно удаляет узлы из базы данных. - Возвращает список успешно удаленных ID узлов. + Очищает settings и удаляет ноды для каждого ps_id. + Возвращает список успешно удаленных ID нод. """ - successfully_deleted = [] + if not node_ids: + return [] - for node_id in node_ids: - success, error_message = await delete_ps_node_by_id_CASCADE(connection, node_id) - if success: - successfully_deleted.append(node_id) + ps_id_rows = await connection.execute( + select(ps_node_table.c.id, ps_node_table.c.ps_id).where(ps_node_table.c.id.in_(node_ids)) + ) + rows = ps_id_rows.mappings().all() + if not rows: + return [] + + ps_to_node_ids = {} + for r in rows: + ps_to_node_ids.setdefault(r["ps_id"], []).append(r["id"]) + + deleted_all = [] + + for ps_id, ids_in_ps in ps_to_node_ids.items(): + await remove_nodes_from_process_schema_settings(connection, ps_id, ids_in_ps) + result = await connection.execute(delete(ps_node_table).where(ps_node_table.c.id.in_(ids_in_ps))) + if result.rowcount and result.rowcount > 0: + deleted_all.extend(ids_in_ps) else: - raise Exception(f"Failed to delete node {node_id}: {error_message}") - return successfully_deleted + raise Exception(f"Failed to delete nodes for ps_id={ps_id}") + + await connection.commit() + return deleted_all -async def remove_node_from_process_schema_settings(connection: AsyncConnection, ps_id: int, node_id: int): +async def remove_nodes_from_process_schema_settings(connection: AsyncConnection, ps_id: int, node_ids: List[int]): """ - Удаляет ноду из поля settings в таблице process_schema. + Удаляет ноды из поля settings в таблице process_schema по списку node_ids. """ from api.db.logic.process_schema import get_process_schema_by_id process_schema = await get_process_schema_by_id(connection, ps_id) - if not process_schema or not process_schema.settings: return settings = process_schema.settings - if "nodes" in settings and isinstance(settings["nodes"], list): + node_ids_set = set(node_ids) settings["nodes"] = [ node_item for node_item in settings["nodes"] @@ -196,7 +182,7 @@ async def remove_node_from_process_schema_settings(connection: AsyncConnection, isinstance(node_item, dict) and "node" in node_item and isinstance(node_item["node"], dict) - and node_item["node"].get("id") == node_id + and node_item["node"].get("id") in node_ids_set ) ]