fix(nextcloud): NULL parent_id before deleting Folder rows on SourceRoot remove
Folders have a self-referential parent_id FK with no ON DELETE rule. A flat DELETE of the whole subtree trips folders_parent_id_fkey because postgres checks the constraint per-row regardless of insertion / list order. Hard-removing 'Taco and Muli - 2024 onward' (35-folder subtree) returned 500 with ForeignKeyViolationError every attempt. Fix: UPDATE folders SET parent_id = NULL WHERE id IN (folder_ids) before the DELETE so the chain is broken cleanly. Same pattern used in prune_missing_photos for the same constraint. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,7 +30,7 @@ from typing import Optional
|
|||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlalchemy import delete, select
|
from sqlalchemy import delete, select, update
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
@@ -332,6 +332,17 @@ async def delete_nextcloud_source_root(
|
|||||||
FolderShare.folder_type == 'folder',
|
FolderShare.folder_type == 'folder',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
# Folders have a self-referential parent_id FK with no
|
||||||
|
# ON DELETE rule. A flat DELETE of the whole subtree trips
|
||||||
|
# `folders_parent_id_fkey` because postgres checks the
|
||||||
|
# constraint per row, regardless of insertion / list order.
|
||||||
|
# NULL the parent_id on every folder we're about to delete
|
||||||
|
# first so the chain breaks cleanly.
|
||||||
|
await db.execute(
|
||||||
|
update(Folder)
|
||||||
|
.where(Folder.id.in_(folder_ids))
|
||||||
|
.values(parent_id=None)
|
||||||
|
)
|
||||||
await db.execute(delete(Folder).where(Folder.id.in_(folder_ids)))
|
await db.execute(delete(Folder).where(Folder.id.in_(folder_ids)))
|
||||||
|
|
||||||
await db.delete(sr)
|
await db.delete(sr)
|
||||||
|
|||||||
Reference in New Issue
Block a user