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
|
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]:
|
async def delete_ps_nodes_delete_handler(connection: AsyncConnection, node_ids: List[int]) -> List[int]:
|
||||||
"""
|
"""
|
||||||
Поочередно удаляет узлы из базы данных.
|
Очищает settings и удаляет ноды для каждого ps_id.
|
||||||
Возвращает список успешно удаленных ID узлов.
|
Возвращает список успешно удаленных ID нод.
|
||||||
"""
|
"""
|
||||||
successfully_deleted = []
|
if not node_ids:
|
||||||
|
return []
|
||||||
|
|
||||||
for node_id in node_ids:
|
ps_id_rows = await connection.execute(
|
||||||
success, error_message = await delete_ps_node_by_id_CASCADE(connection, node_id)
|
select(ps_node_table.c.id, ps_node_table.c.ps_id).where(ps_node_table.c.id.in_(node_ids))
|
||||||
if success:
|
)
|
||||||
successfully_deleted.append(node_id)
|
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:
|
else:
|
||||||
raise Exception(f"Failed to delete node {node_id}: {error_message}")
|
raise Exception(f"Failed to delete nodes for ps_id={ps_id}")
|
||||||
return successfully_deleted
|
|
||||||
|
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
|
from api.db.logic.process_schema import get_process_schema_by_id
|
||||||
|
|
||||||
process_schema = await get_process_schema_by_id(connection, ps_id)
|
process_schema = await get_process_schema_by_id(connection, ps_id)
|
||||||
|
|
||||||
if not process_schema or not process_schema.settings:
|
if not process_schema or not process_schema.settings:
|
||||||
return
|
return
|
||||||
|
|
||||||
settings = process_schema.settings
|
settings = process_schema.settings
|
||||||
|
|
||||||
if "nodes" in settings and isinstance(settings["nodes"], list):
|
if "nodes" in settings and isinstance(settings["nodes"], list):
|
||||||
|
node_ids_set = set(node_ids)
|
||||||
settings["nodes"] = [
|
settings["nodes"] = [
|
||||||
node_item
|
node_item
|
||||||
for node_item in settings["nodes"]
|
for node_item in settings["nodes"]
|
||||||
@@ -196,7 +182,7 @@ async def remove_node_from_process_schema_settings(connection: AsyncConnection,
|
|||||||
isinstance(node_item, dict)
|
isinstance(node_item, dict)
|
||||||
and "node" in node_item
|
and "node" in node_item
|
||||||
and isinstance(node_item["node"], dict)
|
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 будет по несколько отдельных запросов. Неэффективно.