85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
"""
|
|
Run database migration for scheduled_jobs table
|
|
"""
|
|
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 run_migration():
|
|
"""Run the migration SQL script"""
|
|
# Read the migration file
|
|
migration_file = Path(__file__).parent.parent / "migrations" / "add_predefined_jobs_support.sql"
|
|
|
|
with open(migration_file, 'r') as f:
|
|
sql_content = f.read()
|
|
|
|
# Split SQL into individual statements
|
|
# Remove comments and split by semicolon
|
|
statements = []
|
|
current_stmt = []
|
|
in_do_block = False
|
|
|
|
for line in sql_content.split('\n'):
|
|
stripped = line.strip()
|
|
|
|
# Skip comments
|
|
if stripped.startswith('--') or not stripped:
|
|
continue
|
|
|
|
# Handle DO blocks specially
|
|
if stripped.startswith('DO $$'):
|
|
in_do_block = True
|
|
current_stmt.append(line)
|
|
elif stripped == 'END $$;':
|
|
current_stmt.append(line)
|
|
statements.append('\n'.join(current_stmt))
|
|
current_stmt = []
|
|
in_do_block = False
|
|
elif in_do_block or not stripped.endswith(';'):
|
|
current_stmt.append(line)
|
|
else:
|
|
# Regular statement ending with ;
|
|
current_stmt.append(line)
|
|
statements.append('\n'.join(current_stmt))
|
|
current_stmt = []
|
|
|
|
async with engine.begin() as conn:
|
|
print("🔄 Running migration: add_predefined_jobs_support.sql")
|
|
|
|
# Execute each statement separately
|
|
for i, stmt in enumerate(statements):
|
|
if stmt.strip():
|
|
try:
|
|
print(f" Executing statement {i+1}/{len(statements)}...")
|
|
await conn.execute(text(stmt))
|
|
except Exception as e:
|
|
# Some statements might fail if already applied, that's okay
|
|
print(f" ⚠️ Statement {i+1} warning: {e}")
|
|
|
|
print("✅ Migration completed successfully!")
|
|
|
|
# Verify the changes
|
|
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()
|
|
|
|
print("\n📋 Current scheduled_jobs table structure:")
|
|
for row in rows:
|
|
print(f" - {row[0]}: {row[1]} (nullable: {row[2]})")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(run_migration())
|