moving styling and views to be more consistent and for gallery view to be less cumbersome.
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
"""Add app_settings table and expand perceptual_hash to 64 chars for 256-bit hashes
|
||||
|
||||
Revision ID: b26011901
|
||||
Revises: a46e641430b8
|
||||
Create Date: 2026-01-19
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'b26011901'
|
||||
down_revision = 'a46e641430b8'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Create app_settings table
|
||||
op.create_table(
|
||||
'app_settings',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('key', sa.String(length=64), nullable=False),
|
||||
sa.Column('value', sa.Text(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('key')
|
||||
)
|
||||
|
||||
# Expand perceptual_hash column from 16 to 64 chars
|
||||
bind = op.get_bind()
|
||||
dialect = bind.dialect.name
|
||||
|
||||
if dialect == "sqlite":
|
||||
# SQLite requires table recreation for column type changes.
|
||||
# IMPORTANT: When recreating image_record, we must also recreate
|
||||
# image_tags to preserve foreign key relationships.
|
||||
|
||||
# Step 1: Backup image_tags data
|
||||
op.execute("CREATE TABLE image_tags_backup AS SELECT * FROM image_tags")
|
||||
|
||||
# Step 2: Drop image_tags (it references image_record)
|
||||
op.drop_table("image_tags")
|
||||
|
||||
# Step 3: Recreate image_record with new column size
|
||||
with op.batch_alter_table("image_record", recreate="always") as batch_op:
|
||||
batch_op.alter_column(
|
||||
'perceptual_hash',
|
||||
existing_type=sa.String(length=16),
|
||||
type_=sa.String(length=64),
|
||||
existing_nullable=True
|
||||
)
|
||||
|
||||
# Step 4: Recreate image_tags with proper FK constraints
|
||||
op.create_table(
|
||||
"image_tags",
|
||||
sa.Column("image_id", sa.Integer(), nullable=False),
|
||||
sa.Column("tag_id", sa.Integer(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("image_id", "tag_id"),
|
||||
sa.ForeignKeyConstraint(["image_id"], ["image_record.id"], ondelete="CASCADE"),
|
||||
sa.ForeignKeyConstraint(["tag_id"], ["tag.id"], ondelete="CASCADE"),
|
||||
sa.UniqueConstraint("image_id", "tag_id", name="uq_image_tag"),
|
||||
)
|
||||
|
||||
# Step 5: Restore image_tags data
|
||||
op.execute("INSERT INTO image_tags (image_id, tag_id) SELECT image_id, tag_id FROM image_tags_backup")
|
||||
|
||||
# Step 6: Drop backup table
|
||||
op.drop_table("image_tags_backup")
|
||||
else:
|
||||
# PostgreSQL and others can alter directly
|
||||
op.alter_column(
|
||||
'image_record',
|
||||
'perceptual_hash',
|
||||
existing_type=sa.String(length=16),
|
||||
type_=sa.String(length=64),
|
||||
existing_nullable=True
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
dialect = bind.dialect.name
|
||||
|
||||
# Shrink perceptual_hash back to 16 chars (will truncate data!)
|
||||
if dialect == "sqlite":
|
||||
# Same approach as upgrade: backup image_tags, recreate image_record,
|
||||
# then restore image_tags to preserve FK relationships
|
||||
|
||||
# Step 1: Backup image_tags data
|
||||
op.execute("CREATE TABLE image_tags_backup AS SELECT * FROM image_tags")
|
||||
|
||||
# Step 2: Drop image_tags (it references image_record)
|
||||
op.drop_table("image_tags")
|
||||
|
||||
# Step 3: Recreate image_record with old column size
|
||||
with op.batch_alter_table("image_record", recreate="always") as batch_op:
|
||||
batch_op.alter_column(
|
||||
'perceptual_hash',
|
||||
existing_type=sa.String(length=64),
|
||||
type_=sa.String(length=16),
|
||||
existing_nullable=True
|
||||
)
|
||||
|
||||
# Step 4: Recreate image_tags with proper FK constraints
|
||||
op.create_table(
|
||||
"image_tags",
|
||||
sa.Column("image_id", sa.Integer(), nullable=False),
|
||||
sa.Column("tag_id", sa.Integer(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("image_id", "tag_id"),
|
||||
sa.ForeignKeyConstraint(["image_id"], ["image_record.id"], ondelete="CASCADE"),
|
||||
sa.ForeignKeyConstraint(["tag_id"], ["tag.id"], ondelete="CASCADE"),
|
||||
sa.UniqueConstraint("image_id", "tag_id", name="uq_image_tag"),
|
||||
)
|
||||
|
||||
# Step 5: Restore image_tags data
|
||||
op.execute("INSERT INTO image_tags (image_id, tag_id) SELECT image_id, tag_id FROM image_tags_backup")
|
||||
|
||||
# Step 6: Drop backup table
|
||||
op.drop_table("image_tags_backup")
|
||||
else:
|
||||
op.alter_column(
|
||||
'image_record',
|
||||
'perceptual_hash',
|
||||
existing_type=sa.String(length=64),
|
||||
type_=sa.String(length=16),
|
||||
existing_nullable=True
|
||||
)
|
||||
|
||||
# Drop app_settings table
|
||||
op.drop_table('app_settings')
|
||||
Reference in New Issue
Block a user