From f27bd953829f0e0a2f34f809f28dc23c0e88310b Mon Sep 17 00:00:00 2001 From: jnMetaCode <1394485448@qq.com> Date: Mon, 16 Mar 2026 19:24:22 +0800 Subject: [PATCH] fix: change chunk FK to CASCADE so doc deletion removes linked memory units (#580) The foreign key from memory_units.chunk_id to chunks.chunk_id used ON DELETE SET NULL, which left ghost memory_units rows (chunk_id nulled out, no parent document) after a document was deleted. Switching to ON DELETE CASCADE lets the existing document -> chunks -> memory_units cascade clean up everything in one pass. Closes #572 Signed-off-by: JiangNan <1394485448@qq.com> --- .../f6g7h8i9j0k1_chunk_fk_cascade_delete.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 hindsight-api-slim/hindsight_api/alembic/versions/f6g7h8i9j0k1_chunk_fk_cascade_delete.py diff --git a/hindsight-api-slim/hindsight_api/alembic/versions/f6g7h8i9j0k1_chunk_fk_cascade_delete.py b/hindsight-api-slim/hindsight_api/alembic/versions/f6g7h8i9j0k1_chunk_fk_cascade_delete.py new file mode 100644 index 00000000..f0311496 --- /dev/null +++ b/hindsight-api-slim/hindsight_api/alembic/versions/f6g7h8i9j0k1_chunk_fk_cascade_delete.py @@ -0,0 +1,38 @@ +"""chunk_fk_cascade_delete + +Revision ID: f6g7h8i9j0k1 +Revises: e5f6g7h8i9j0 +Create Date: 2026-03-16 00:00:00.000000 + +""" + +from collections.abc import Sequence + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "f6g7h8i9j0k1" +down_revision: str | Sequence[str] | None = "e5f6g7h8i9j0" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + """Change memory_units.chunk_id FK from SET NULL to CASCADE. + + When a document is deleted the CASCADE reaches chunks first; with SET NULL + the memory_units rows survived with chunk_id = NULL, leaving ghost records. + Switching to CASCADE ensures they are removed together with their chunk. + """ + op.drop_constraint("memory_units_chunk_fkey", "memory_units", type_="foreignkey") + op.create_foreign_key( + "memory_units_chunk_fkey", "memory_units", "chunks", ["chunk_id"], ["chunk_id"], ondelete="CASCADE" + ) + + +def downgrade() -> None: + """Revert to SET NULL behaviour.""" + op.drop_constraint("memory_units_chunk_fkey", "memory_units", type_="foreignkey") + op.create_foreign_key( + "memory_units_chunk_fkey", "memory_units", "chunks", ["chunk_id"], ["chunk_id"], ondelete="SET NULL" + )