#!/usr/bin/env python """ SQLite migration for Story 3.1 Makes custom_hostname nullable and adds unique constraint to pull_zone_bcdn_hostname """ import sqlite3 import sys def migrate(): conn = sqlite3.connect('content_automation.db') cursor = conn.cursor() try: print("Starting migration for Story 3.1...") # Check if migration already applied cursor.execute("PRAGMA table_info(site_deployments)") columns = cursor.fetchall() custom_hostname_col = [col for col in columns if col[1] == 'custom_hostname'][0] is_nullable = custom_hostname_col[3] == 0 # 0 = nullable, 1 = not null if is_nullable: print("āœ“ Migration already applied (custom_hostname is already nullable)") conn.close() return print("Step 1: Backing up existing data...") cursor.execute("SELECT COUNT(*) FROM site_deployments") count = cursor.fetchone()[0] print(f" Found {count} existing site deployment(s)") print("Step 2: Creating new table with updated schema...") cursor.execute(""" CREATE TABLE site_deployments_new ( id INTEGER PRIMARY KEY AUTOINCREMENT, site_name VARCHAR(255) NOT NULL, custom_hostname VARCHAR(255) UNIQUE, storage_zone_id INTEGER NOT NULL, storage_zone_name VARCHAR(255) NOT NULL, storage_zone_password VARCHAR(255) NOT NULL, storage_zone_region VARCHAR(10) NOT NULL, pull_zone_id INTEGER NOT NULL, pull_zone_bcdn_hostname VARCHAR(255) NOT NULL UNIQUE, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ) """) print("Step 3: Copying data from old table...") cursor.execute(""" INSERT INTO site_deployments_new SELECT * FROM site_deployments """) print("Step 4: Dropping old table...") cursor.execute("DROP TABLE site_deployments") print("Step 5: Renaming new table...") cursor.execute("ALTER TABLE site_deployments_new RENAME TO site_deployments") # Create indexes print("Step 6: Creating indexes...") cursor.execute("CREATE INDEX IF NOT EXISTS ix_site_deployments_custom_hostname ON site_deployments (custom_hostname)") conn.commit() print("\nāœ“ Migration completed successfully!") print(f" - custom_hostname is now nullable") print(f" - pull_zone_bcdn_hostname has unique constraint") print(f" - {count} record(s) migrated") except Exception as e: conn.rollback() print(f"\nāœ— Migration failed: {e}", file=sys.stderr) sys.exit(1) finally: conn.close() if __name__ == "__main__": migrate()