mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
fix: make migration 109 idempotent
This commit is contained in:
parent
10e0e733af
commit
2a809d0418
1 changed files with 65 additions and 55 deletions
|
|
@ -11,6 +11,7 @@ index to correctly handle NULL parent_id at root level.
|
|||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
|
@ -21,67 +22,76 @@ depends_on: str | Sequence[str] | None = None
|
|||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"folders",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("name", sa.String(255), nullable=False, index=True),
|
||||
sa.Column("position", sa.String(50), nullable=False, index=True),
|
||||
sa.Column(
|
||||
"parent_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("folders.id", ondelete="CASCADE"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"search_space_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("searchspaces.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"created_by_id",
|
||||
sa.Uuid(),
|
||||
sa.ForeignKey("user.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.TIMESTAMP(timezone=True),
|
||||
nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
),
|
||||
sa.Column(
|
||||
"updated_at",
|
||||
sa.TIMESTAMP(timezone=True),
|
||||
nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
),
|
||||
)
|
||||
conn = op.get_bind()
|
||||
inspector = inspect(conn)
|
||||
existing_tables = inspector.get_table_names()
|
||||
|
||||
if "folders" not in existing_tables:
|
||||
op.create_table(
|
||||
"folders",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("name", sa.String(255), nullable=False, index=True),
|
||||
sa.Column("position", sa.String(50), nullable=False, index=True),
|
||||
sa.Column(
|
||||
"parent_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("folders.id", ondelete="CASCADE"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"search_space_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("searchspaces.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"created_by_id",
|
||||
sa.Uuid(),
|
||||
sa.ForeignKey("user.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.TIMESTAMP(timezone=True),
|
||||
nullable=False,
|
||||
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.
|
||||
# PostgreSQL treats NULL != NULL in regular unique constraints, so a standard
|
||||
# UniqueConstraint(search_space_id, parent_id, name) would allow duplicate
|
||||
# folder names at the root level.
|
||||
op.execute(
|
||||
"""
|
||||
CREATE UNIQUE INDEX uq_folder_space_parent_name
|
||||
ON folders (search_space_id, COALESCE(parent_id, 0), name);
|
||||
"""
|
||||
)
|
||||
existing_indexes = [idx["name"] for idx in inspector.get_indexes("folders")]
|
||||
if "uq_folder_space_parent_name" not in existing_indexes:
|
||||
op.execute(
|
||||
"""
|
||||
CREATE UNIQUE INDEX uq_folder_space_parent_name
|
||||
ON folders (search_space_id, COALESCE(parent_id, 0), name);
|
||||
"""
|
||||
)
|
||||
|
||||
op.add_column(
|
||||
"documents",
|
||||
sa.Column(
|
||||
"folder_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("folders.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
),
|
||||
)
|
||||
existing_columns = [col["name"] for col in inspector.get_columns("documents")]
|
||||
if "folder_id" not in existing_columns:
|
||||
op.add_column(
|
||||
"documents",
|
||||
sa.Column(
|
||||
"folder_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("folders.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue