""" Fix enum type and add columns """ import asyncio import sys from pathlib import Path # Add backend to path sys.path.insert(0, str(Path(__file__).parent.parent)) from sqlalchemy import text from app.database import engine async def fix_enum_and_migrate(): """Fix enum type and add columns""" async with engine.begin() as conn: # First check enum values result = await conn.execute(text(""" SELECT enumlabel FROM pg_enum WHERE enumtypid = 'jobtype'::regtype ORDER BY enumsortorder """)) enum_values = [row[0] for row in result.fetchall()] print(f"Current enum values: {enum_values}") # Add missing enum values if needed if 'predefined' not in enum_values: await conn.execute(text("ALTER TYPE jobtype ADD VALUE 'predefined'")) print("āœ… Added 'predefined' to enum") if 'custom_code' not in enum_values: await conn.execute(text("ALTER TYPE jobtype ADD VALUE 'custom_code'")) print("āœ… Added 'custom_code' to enum") # Now add columns in separate transaction async with engine.begin() as conn: print("\nšŸ”„ Adding columns to scheduled_jobs table...") # Add job_type column try: await conn.execute(text(""" ALTER TABLE scheduled_jobs ADD COLUMN job_type jobtype DEFAULT 'custom_code'::jobtype NOT NULL """)) print("āœ… Added job_type column") except Exception as e: if "already exists" in str(e): print("ā„¹ļø job_type column already exists") else: raise # Add predefined_function column try: await conn.execute(text(""" ALTER TABLE scheduled_jobs ADD COLUMN predefined_function VARCHAR(100) """)) print("āœ… Added predefined_function column") except Exception as e: if "already exists" in str(e): print("ā„¹ļø predefined_function column already exists") else: raise # Add function_params column try: await conn.execute(text(""" ALTER TABLE scheduled_jobs ADD COLUMN function_params JSONB DEFAULT '{}'::jsonb """)) print("āœ… Added function_params column") except Exception as e: if "already exists" in str(e): print("ā„¹ļø function_params column already exists") else: raise # Set defaults and constraints in separate transaction async with engine.begin() as conn: # Set default for future records await conn.execute(text(""" ALTER TABLE scheduled_jobs ALTER COLUMN job_type SET DEFAULT 'predefined'::jobtype """)) print("āœ… Set default job_type to 'predefined'") # Drop and recreate check constraint await conn.execute(text(""" ALTER TABLE scheduled_jobs DROP CONSTRAINT IF EXISTS chk_job_type_fields """)) await conn.execute(text(""" ALTER TABLE scheduled_jobs ADD CONSTRAINT chk_job_type_fields CHECK ( (job_type = 'predefined' AND predefined_function IS NOT NULL) OR (job_type = 'custom_code' AND python_code IS NOT NULL) ) """)) print("āœ… Added check constraint") print("\nšŸ“‹ Final table structure:") result = await conn.execute(text(""" SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_name = 'scheduled_jobs' ORDER BY ordinal_position """)) rows = result.fetchall() for row in rows: print(f" - {row[0]}: {row[1]} (nullable: {row[2]})") if __name__ == "__main__": asyncio.run(fix_enum_and_migrate())