Develop #16
@@ -0,0 +1,54 @@
|
||||
"""Make the scripts workspace/name/type unique index soft-delete aware.
|
||||
|
||||
The old unique index ``uk_scripts_workspace_name`` on
|
||||
``(workspace_id, script_name, script_type)`` blocked re-uploading a
|
||||
script after it had been soft-deleted, because the deleted row was still
|
||||
part of the index.
|
||||
|
||||
Replace it with ``uk_scripts_workspace_name_active`` on
|
||||
``(workspace_id, script_name, script_type, deleted_at)``. In MySQL a
|
||||
unique index treats ``NULL`` values as distinct, so a new active row
|
||||
(``deleted_at IS NULL``) no longer conflicts with a previously deleted
|
||||
row (``deleted_at IS NOT NULL``), while two active rows with the same
|
||||
name still conflict as expected.
|
||||
|
||||
Revision ID: 47a76cd261fd
|
||||
Revises: 3ba4d8489f36
|
||||
Create Date: 2026-08-14
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "47a76cd261fd"
|
||||
down_revision: str | Sequence[str] | None = "3ba4d8489f36"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.drop_index(
|
||||
"uk_scripts_workspace_name",
|
||||
table_name="scripts",
|
||||
)
|
||||
op.create_index(
|
||||
"uk_scripts_workspace_name_active",
|
||||
"scripts",
|
||||
["workspace_id", "script_name", "script_type", "deleted_at"],
|
||||
unique=True,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index(
|
||||
"uk_scripts_workspace_name_active",
|
||||
table_name="scripts",
|
||||
)
|
||||
op.create_index(
|
||||
"uk_scripts_workspace_name",
|
||||
"scripts",
|
||||
["workspace_id", "script_name", "script_type"],
|
||||
unique=True,
|
||||
)
|
||||
@@ -0,0 +1,63 @@
|
||||
"""Drop unique indexes on Scripts and DataResources.
|
||||
|
||||
StorageObjects now carries the physical uniqueness guarantees:
|
||||
- ``uk_storage_bucket_key``
|
||||
- ``uk_storage_workspace_path``
|
||||
|
||||
Scripts and DataResources therefore no longer need their own unique
|
||||
indexes on ``current_object_id`` / ``storage_object_id``, and the
|
||||
soft-delete-aware ``uk_scripts_workspace_name_active`` index is also
|
||||
removed. Re-uploading a previously soft-deleted script or resource is
|
||||
allowed because the StorageObjects layer enforces path uniqueness only
|
||||
for active objects.
|
||||
|
||||
Revision ID: a1b2c3d4e5f6
|
||||
Revises: 47a76cd261fd
|
||||
Create Date: 2026-08-14
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "a1b2c3d4e5f6"
|
||||
down_revision: str | Sequence[str] | None = "47a76cd261fd"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.drop_index(
|
||||
"uk_scripts_workspace_name_active",
|
||||
table_name="scripts",
|
||||
)
|
||||
op.drop_index(
|
||||
"uk_scripts_current_object",
|
||||
table_name="scripts",
|
||||
)
|
||||
op.drop_index(
|
||||
"uk_data_resources_object",
|
||||
table_name="data_resources",
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.create_index(
|
||||
"uk_scripts_workspace_name_active",
|
||||
"scripts",
|
||||
["workspace_id", "script_name", "script_type", "deleted_at"],
|
||||
unique=True,
|
||||
)
|
||||
op.create_index(
|
||||
"uk_scripts_current_object",
|
||||
"scripts",
|
||||
["current_object_id"],
|
||||
unique=True,
|
||||
)
|
||||
op.create_index(
|
||||
"uk_data_resources_object",
|
||||
"data_resources",
|
||||
["storage_object_id"],
|
||||
unique=True,
|
||||
)
|
||||
Reference in New Issue
Block a user