"""Initial schema Revision ID: 001 Revises: Create Date: 2024-01-01 00:00:00.000000 """ from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision = '001' down_revision = None branch_labels = None depends_on = None def upgrade() -> None: # Create schema op.execute("CREATE SCHEMA IF NOT EXISTS moviemap") # Create enums op.execute(""" DO $$ BEGIN CREATE TYPE moviemap.source_kind AS ENUM ('radarr', 'sonarr', 'lidarr'); EXCEPTION WHEN duplicate_object THEN null; END $$; """) op.execute(""" DO $$ BEGIN CREATE TYPE moviemap.media_type AS ENUM ('movie', 'show', 'music'); EXCEPTION WHEN duplicate_object THEN null; END $$; """) op.execute(""" DO $$ BEGIN CREATE TYPE moviemap.watched_media_type AS ENUM ('movie', 'show'); EXCEPTION WHEN duplicate_object THEN null; END $$; """) # Create source table op.execute(""" CREATE TABLE IF NOT EXISTS moviemap.source ( id SERIAL PRIMARY KEY, kind moviemap.source_kind NOT NULL UNIQUE, base_url TEXT NOT NULL, enabled BOOLEAN NOT NULL DEFAULT true, last_sync_at TIMESTAMPTZ ) """) # Create media_item table op.execute(""" CREATE TABLE IF NOT EXISTS moviemap.media_item ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), source_kind moviemap.source_kind NOT NULL, source_item_id INTEGER NOT NULL, title TEXT NOT NULL, year INTEGER, media_type moviemap.media_type NOT NULL, arr_raw JSONB, UNIQUE (source_kind, source_item_id) ) """) # Create media_country table op.execute(""" CREATE TABLE IF NOT EXISTS moviemap.media_country ( media_item_id UUID NOT NULL REFERENCES moviemap.media_item(id) ON DELETE CASCADE, country_code CHAR(2) NOT NULL, weight SMALLINT NOT NULL DEFAULT 1, PRIMARY KEY (media_item_id, country_code) ) """) # Create watched_item table op.execute(""" CREATE TABLE IF NOT EXISTS moviemap.watched_item ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), media_type moviemap.watched_media_type NOT NULL, title TEXT NOT NULL, year INTEGER, country_code CHAR(2) NOT NULL, watched_at TIMESTAMPTZ, notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ) """) # Create manual_pin table op.execute(""" CREATE TABLE IF NOT EXISTS moviemap.manual_pin ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), country_code CHAR(2) NOT NULL, label TEXT, pinned_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ) """) # Create indexes op.execute("CREATE INDEX IF NOT EXISTS idx_media_item_source ON moviemap.media_item (source_kind, source_item_id)") op.execute("CREATE INDEX IF NOT EXISTS idx_media_country_code ON moviemap.media_country (country_code)") op.execute("CREATE INDEX IF NOT EXISTS idx_watched_country ON moviemap.watched_item (country_code)") op.execute("CREATE INDEX IF NOT EXISTS idx_watched_media_type ON moviemap.watched_item (media_type)") op.execute("CREATE INDEX IF NOT EXISTS idx_pin_country ON moviemap.manual_pin (country_code)") def downgrade() -> None: op.execute("DROP INDEX IF EXISTS moviemap.idx_pin_country") op.execute("DROP INDEX IF EXISTS moviemap.idx_watched_media_type") op.execute("DROP INDEX IF EXISTS moviemap.idx_watched_country") op.execute("DROP INDEX IF EXISTS moviemap.idx_media_country_code") op.execute("DROP INDEX IF EXISTS moviemap.idx_media_item_source") op.execute("DROP TABLE IF EXISTS moviemap.manual_pin") op.execute("DROP TABLE IF EXISTS moviemap.watched_item") op.execute("DROP TABLE IF EXISTS moviemap.media_country") op.execute("DROP TABLE IF EXISTS moviemap.media_item") op.execute("DROP TABLE IF EXISTS moviemap.source") op.execute("DROP TYPE IF EXISTS moviemap.watched_media_type") op.execute("DROP TYPE IF EXISTS moviemap.media_type") op.execute("DROP TYPE IF EXISTS moviemap.source_kind") op.execute("DROP SCHEMA IF EXISTS moviemap")