76 lines
2.7 KiB
Python
76 lines
2.7 KiB
Python
"""Update Access model with hierarchical permission support
|
|
|
|
Revision ID: a2b3c4d5e6f7
|
|
Revises: a1b2c3d4e5f6
|
|
Create Date: 2026-03-05 10:00:00.000000
|
|
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = 'a2b3c4d5e6f7'
|
|
down_revision = 'a1b2c3d4e5f6'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# FIRST: Drop any existing unique constraint on `name` (constraints may be named differently depending on DB)
|
|
op.execute("ALTER TABLE accesses DROP CONSTRAINT IF EXISTS uq_accesses_name CASCADE")
|
|
op.execute("ALTER TABLE accesses DROP CONSTRAINT IF EXISTS accesses_name_key CASCADE")
|
|
# also drop postgresql-generated index if it survived
|
|
op.execute("DROP INDEX IF EXISTS accesses_name_key")
|
|
|
|
# Add new columns to accesses table (all nullable first)
|
|
op.add_column('accesses', sa.Column('access_code', sa.String(255), nullable=True))
|
|
op.add_column('accesses', sa.Column('category', sa.String(100), nullable=True))
|
|
op.add_column('accesses', sa.Column('parent_id', sa.Integer(), nullable=True))
|
|
|
|
# Create indexes on new columns
|
|
op.create_index('ix_access_code', 'accesses', ['access_code'])
|
|
op.create_index('ix_category', 'accesses', ['category'])
|
|
op.create_index('ix_accesses_parent_id', 'accesses', ['parent_id'])
|
|
|
|
# Set default values from existing 'name' field
|
|
op.execute("""
|
|
UPDATE accesses
|
|
SET access_code = LOWER(REPLACE(name, ' ', '_')),
|
|
category = 'General'
|
|
WHERE access_code IS NULL
|
|
""")
|
|
|
|
# Now make columns NOT NULL
|
|
op.alter_column('accesses', 'access_code', existing_type=sa.String(255), nullable=False)
|
|
op.alter_column('accesses', 'category', existing_type=sa.String(100), nullable=False)
|
|
|
|
# Create unique constraint on access_code
|
|
op.create_unique_constraint('uq_accesses_access_code', 'accesses', ['access_code'])
|
|
|
|
# Create foreign key for parent_id
|
|
op.create_foreign_key('fk_accesses_parent_id', 'accesses', 'accesses', ['parent_id'], ['id'], ondelete='CASCADE')
|
|
|
|
|
|
def downgrade() -> None:
|
|
# Drop foreign key
|
|
op.drop_constraint('fk_accesses_parent_id', 'accesses', type_='foreignkey')
|
|
|
|
# Drop unique constraint
|
|
op.drop_constraint('uq_accesses_access_code', 'accesses', type_='unique')
|
|
|
|
# Drop indexes
|
|
op.drop_index('ix_accesses_parent_id', 'accesses')
|
|
op.drop_index('ix_category', 'accesses')
|
|
op.drop_index('ix_access_code', 'accesses')
|
|
|
|
# Drop columns
|
|
op.drop_column('accesses', 'parent_id')
|
|
op.drop_column('accesses', 'category')
|
|
op.drop_column('accesses', 'access_code')
|
|
|
|
# Re-add unique constraint on 'name'
|
|
op.create_unique_constraint('uq_accesses_name', 'accesses', ['name'])
|
|
|
|
|