switched to tagging and added views to support it, in progress for other tagging functions.
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
"""Add ON DELETE CASCADE to image_tags; SET NULL for ArchiveRecord.tag_id
|
||||
|
||||
Revision ID: 486bf4238616
|
||||
Revises: fe4dfdd6616c
|
||||
Create Date: 2025-08-14 22:41:40.746201
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '486bf4238616'
|
||||
down_revision = 'fe4dfdd6616c'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers
|
||||
revision = "486bf4238616"
|
||||
down_revision = "fe4dfdd6616c"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
bind = op.get_bind()
|
||||
dialect = bind.dialect.name
|
||||
|
||||
if dialect == "sqlite":
|
||||
# --- image_tags: recreate with CASCADE FKs ---
|
||||
op.create_table(
|
||||
"image_tags_new",
|
||||
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"),
|
||||
)
|
||||
op.execute("INSERT INTO image_tags_new (image_id, tag_id) SELECT image_id, tag_id FROM image_tags")
|
||||
op.drop_table("image_tags")
|
||||
op.rename_table("image_tags_new", "image_tags")
|
||||
|
||||
# --- archive_record.tag_id: leave FK as-is on SQLite (dev) ---
|
||||
# We do not alter ondelete here due to SQLite ALTER limitations.
|
||||
# Your reset route deletes in safe order, so this is fine for testing.
|
||||
|
||||
else:
|
||||
# --- Postgres path: drop/recreate FKs normally ---
|
||||
# image_tags -> ON DELETE CASCADE
|
||||
op.drop_constraint("image_tags_image_id_fkey", "image_tags", type_="foreignkey")
|
||||
op.drop_constraint("image_tags_tag_id_fkey", "image_tags", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"image_tags_image_id_fkey",
|
||||
"image_tags",
|
||||
"image_record",
|
||||
["image_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
op.create_foreign_key(
|
||||
"image_tags_tag_id_fkey",
|
||||
"image_tags",
|
||||
"tag",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
|
||||
# archive_record.tag_id -> NULLable + ON DELETE SET NULL
|
||||
op.alter_column("archive_record", "tag_id", existing_type=sa.Integer(), nullable=True)
|
||||
op.drop_constraint("archive_record_tag_id_fkey", "archive_record", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"archive_record_tag_id_fkey",
|
||||
"archive_record",
|
||||
"tag",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
ondelete="SET NULL",
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
dialect = bind.dialect.name
|
||||
|
||||
if dialect == "sqlite":
|
||||
# revert image_tags to non-cascade FKs (recreate again)
|
||||
op.create_table(
|
||||
"image_tags_old",
|
||||
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"]),
|
||||
sa.ForeignKeyConstraint(["tag_id"], ["tag.id"]),
|
||||
sa.UniqueConstraint("image_id", "tag_id", name="uq_image_tag"),
|
||||
)
|
||||
op.execute("INSERT INTO image_tags_old (image_id, tag_id) SELECT image_id, tag_id FROM image_tags")
|
||||
op.drop_table("image_tags")
|
||||
op.rename_table("image_tags_old", "image_tags")
|
||||
|
||||
# archive_record left unchanged in upgrade, nothing to revert here.
|
||||
|
||||
else:
|
||||
# Postgres: revert to no-cascade FKs and non-nullable tag_id
|
||||
op.drop_constraint("archive_record_tag_id_fkey", "archive_record", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"archive_record_tag_id_fkey",
|
||||
"archive_record",
|
||||
"tag",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
)
|
||||
op.alter_column("archive_record", "tag_id", existing_type=sa.Integer(), nullable=False)
|
||||
|
||||
op.drop_constraint("image_tags_tag_id_fkey", "image_tags", type_="foreignkey")
|
||||
op.drop_constraint("image_tags_image_id_fkey", "image_tags", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"image_tags_image_id_fkey",
|
||||
"image_tags",
|
||||
"image_record",
|
||||
["image_id"],
|
||||
["id"],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
"image_tags_tag_id_fkey",
|
||||
"image_tags",
|
||||
"tag",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
)
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Drop ImageRecord.artist (use tags instead)
|
||||
|
||||
Revision ID: a46e641430b8
|
||||
Revises: 486bf4238616
|
||||
Create Date: 2025-08-15 00:52:13.293364
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'a46e641430b8'
|
||||
down_revision = '486bf4238616'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
bind = op.get_bind()
|
||||
dialect = bind.dialect.name
|
||||
|
||||
if dialect == "sqlite":
|
||||
# Recreate table without the 'artist' column (SQLite can't drop columns natively)
|
||||
with op.batch_alter_table("image_record", recreate="always") as batch_op:
|
||||
batch_op.drop_column("artist")
|
||||
else:
|
||||
# Postgres / others can drop directly
|
||||
op.drop_column("image_record", "artist")
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
dialect = bind.dialect.name
|
||||
|
||||
if dialect == "sqlite":
|
||||
with op.batch_alter_table("image_record", recreate="always") as batch_op:
|
||||
batch_op.add_column(sa.Column("artist", sa.String(length=255), nullable=True))
|
||||
else:
|
||||
op.add_column("image_record", sa.Column("artist", sa.String(length=255), nullable=True))
|
||||
Reference in New Issue
Block a user