diff --git a/common/src/common/db/models/storage.py b/common/src/common/db/models/storage.py index 05bbc1c..3380223 100644 --- a/common/src/common/db/models/storage.py +++ b/common/src/common/db/models/storage.py @@ -20,7 +20,6 @@ class StorageObjects(Base): Index("fk_storage_created_by", "created_by"), Index("idx_storage_content_hash", "content_hash"), Index("idx_storage_owner", "owner_user_id", "object_status"), - Index("idx_storage_parent", "parent_object_id"), Index( "idx_storage_workspace_path", "workspace_id", @@ -40,7 +39,7 @@ class StorageObjects(Base): "object_key_hash_active", unique=True, ), - {"comment": "Workspace 文件和 RustFS 对象的统一元数据"}, + {"comment": "Workspace 文件和 RustFS 对象的统一元数据;目录树走 materialized path (relative_path),不要 join 邻接表列——已删除。"}, ) storage_object_id: Mapped[str] = mapped_column(CHAR(26), primary_key=True) @@ -86,7 +85,6 @@ class StorageObjects(Base): server_default=text("CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"), ) owner_user_id: Mapped[str | None] = mapped_column(CHAR(26)) - parent_object_id: Mapped[str | None] = mapped_column(CHAR(26)) relative_path: Mapped[str | None] = mapped_column( String(1024), comment="Workspace 相对路径" ) diff --git a/migrations/versions/f7a8b9c0d1e2_drop_storage_parent.py b/migrations/versions/f7a8b9c0d1e2_drop_storage_parent.py new file mode 100644 index 0000000..fba2605 --- /dev/null +++ b/migrations/versions/f7a8b9c0d1e2_drop_storage_parent.py @@ -0,0 +1,56 @@ +"""drop dead storage_objects.parent_object_id column and idx_storage_parent + +Revision ID: f7a8b9c0d1e2 +Revises: e1f2a3b4c5d6 +Create Date: 2026-08-21 + +Removes a never-written column and its orphaned index. Tree structure is +maintained entirely via relative_path (materialized path); see +backend/src/backend/scripts.py (list_workspace_tree / list_workspace_directories). + +MySQL 8.0 does not support DROP INDEX IF EXISTS / DROP COLUMN IF EXISTS, +so the calls below are unconditional. +""" + +from collections.abc import Sequence + +import sqlalchemy as sa +from alembic import op +from sqlalchemy.dialects import mysql + +# revision identifiers, used by Alembic. +revision: str = "f7a8b9c0d1e2" +down_revision: str | Sequence[str] | None = "e1f2a3b4c5d6" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + """Drop the dead index, then the dead column.""" + op.drop_index("idx_storage_parent", table_name="storage_objects") + op.drop_column("storage_objects", "parent_object_id") + # Refresh the table comment so the warning reaches the DB, not just the ORM. + op.execute( + "ALTER TABLE storage_objects " + "COMMENT = 'Workspace 文件和 RustFS 对象的统一元数据;" + "目录树走 materialized path (relative_path)," + "不要 join 邻接表列——已删除。'" + ) + + +def downgrade() -> None: + """Recreate the column and index for rollback.""" + op.add_column( + "storage_objects", + sa.Column("parent_object_id", mysql.CHAR(length=26), nullable=True), + ) + op.create_index( + "idx_storage_parent", + "storage_objects", + ["parent_object_id"], + unique=False, + ) + op.execute( + "ALTER TABLE storage_objects " + "COMMENT = 'Workspace 文件和 RustFS 对象的统一元数据'" + ) \ No newline at end of file