feat: delete ps node #20
@@ -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
|
||||
)
|
||||
|
ivan.dev marked this conversation as resolved
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user
Ну и здесь на каждый id будет по несколько отдельных запросов. Неэффективно.