fix: 修复产品删除 500 — ImportError + FK 自引用约束

- 修正 TaskLog 导入路径:app.models.task → app.models.task_log
- 删除任务前先切断 parent_task_id 自引用外键
- 删除产品前先切断 parent_product_id 自引用外键
- 真正执行 delete(TaskRecord) 和 delete(TaskLog) 替代空 select
This commit is contained in:
2026-08-10 17:36:48 +08:00
parent ba060cbb5e
commit 2440e9bdaa

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
import uuid import uuid
from fastapi import HTTPException, status from fastapi import HTTPException, status
from sqlalchemy import select, or_, cast, String from sqlalchemy import select, or_, cast, String, delete, update
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
@ -503,20 +503,32 @@ async def delete_product(db: AsyncSession, product_id: uuid.UUID) -> None:
"""删除产品及其关联任务""" """删除产品及其关联任务"""
product = await get_product(db, product_id) product = await get_product(db, product_id)
# 删除关联任务记录
from app.models.task import TaskRecord from app.models.task import TaskRecord
from app.models.task_log import TaskLog
# 🚀 1. 切断产品自引用:子产品的 parent_product_id 置空
await db.execute(
update(Product).where(Product.parent_product_id == product_id).values(parent_product_id=None)
)
# 2. 查询所有关联任务
tasks_result = await db.execute( tasks_result = await db.execute(
select(Task).where(Task.product_id == product_id) select(Task).where(Task.product_id == product_id)
) )
tasks = tasks_result.scalars().all() tasks = tasks_result.scalars().all()
# 🚀 3. 切断任务自引用:子任务的 parent_task_id 置空
for task in tasks: for task in tasks:
await db.execute( await db.execute(
select(TaskRecord).where(TaskRecord.task_id == task.id) update(Task).where(Task.parent_task_id == task.id).values(parent_task_id=None)
) )
# 级联删除已在模型中定义,直接删任务
# 删除产品task 有外键 CASCADE检查模型 # 4. 删除任务记录、日志、任务本身
# 手动删关联任务确保完整
for task in tasks: for task in tasks:
await db.execute(delete(TaskRecord).where(TaskRecord.task_id == task.id))
await db.execute(delete(TaskLog).where(TaskLog.task_id == task.id))
await db.delete(task) await db.delete(task)
# 5. 删除产品product_messages 有 ON DELETE CASCADE 自动级联)
await db.delete(product) await db.delete(product)
await db.commit() await db.commit()