Merge pull request #1069 from CREDO23/fix/zero-cache

[Fix] Make migration 109 idempotent
This commit is contained in:
Rohan Verma 2026-04-01 02:19:53 -07:00 committed by GitHub
commit b1631cd6f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -11,6 +11,7 @@ index to correctly handle NULL parent_id at root level.
from collections.abc import Sequence from collections.abc import Sequence
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy import inspect
from alembic import op from alembic import op
@ -21,67 +22,76 @@ depends_on: str | Sequence[str] | None = None
def upgrade() -> None: def upgrade() -> None:
op.create_table( conn = op.get_bind()
"folders", inspector = inspect(conn)
sa.Column("id", sa.Integer(), primary_key=True, index=True), existing_tables = inspector.get_table_names()
sa.Column("name", sa.String(255), nullable=False, index=True),
sa.Column("position", sa.String(50), nullable=False, index=True), if "folders" not in existing_tables:
sa.Column( op.create_table(
"parent_id", "folders",
sa.Integer(), sa.Column("id", sa.Integer(), primary_key=True, index=True),
sa.ForeignKey("folders.id", ondelete="CASCADE"), sa.Column("name", sa.String(255), nullable=False, index=True),
nullable=True, sa.Column("position", sa.String(50), nullable=False, index=True),
index=True, sa.Column(
), "parent_id",
sa.Column( sa.Integer(),
"search_space_id", sa.ForeignKey("folders.id", ondelete="CASCADE"),
sa.Integer(), nullable=True,
sa.ForeignKey("searchspaces.id", ondelete="CASCADE"), index=True,
nullable=False, ),
index=True, sa.Column(
), "search_space_id",
sa.Column( sa.Integer(),
"created_by_id", sa.ForeignKey("searchspaces.id", ondelete="CASCADE"),
sa.Uuid(), nullable=False,
sa.ForeignKey("user.id", ondelete="SET NULL"), index=True,
nullable=True, ),
index=True, sa.Column(
), "created_by_id",
sa.Column( sa.Uuid(),
"created_at", sa.ForeignKey("user.id", ondelete="SET NULL"),
sa.TIMESTAMP(timezone=True), nullable=True,
nullable=False, index=True,
server_default=sa.func.now(), ),
), sa.Column(
sa.Column( "created_at",
"updated_at", sa.TIMESTAMP(timezone=True),
sa.TIMESTAMP(timezone=True), nullable=False,
nullable=False, server_default=sa.func.now(),
server_default=sa.func.now(), ),
), sa.Column(
) "updated_at",
sa.TIMESTAMP(timezone=True),
nullable=False,
server_default=sa.func.now(),
),
)
# Expression-based unique index: COALESCE(parent_id, 0) handles NULL correctly. # Expression-based unique index: COALESCE(parent_id, 0) handles NULL correctly.
# PostgreSQL treats NULL != NULL in regular unique constraints, so a standard # PostgreSQL treats NULL != NULL in regular unique constraints, so a standard
# UniqueConstraint(search_space_id, parent_id, name) would allow duplicate # UniqueConstraint(search_space_id, parent_id, name) would allow duplicate
# folder names at the root level. # folder names at the root level.
op.execute( existing_indexes = [idx["name"] for idx in inspector.get_indexes("folders")]
""" if "uq_folder_space_parent_name" not in existing_indexes:
CREATE UNIQUE INDEX uq_folder_space_parent_name op.execute(
ON folders (search_space_id, COALESCE(parent_id, 0), name); """
""" CREATE UNIQUE INDEX uq_folder_space_parent_name
) ON folders (search_space_id, COALESCE(parent_id, 0), name);
"""
)
op.add_column( existing_columns = [col["name"] for col in inspector.get_columns("documents")]
"documents", if "folder_id" not in existing_columns:
sa.Column( op.add_column(
"folder_id", "documents",
sa.Integer(), sa.Column(
sa.ForeignKey("folders.id", ondelete="SET NULL"), "folder_id",
nullable=True, sa.Integer(),
index=True, sa.ForeignKey("folders.id", ondelete="SET NULL"),
), nullable=True,
) index=True,
),
)
def downgrade() -> None: def downgrade() -> None: