yurt
This commit is contained in:
206
migrate_session_changes.py
Executable file
206
migrate_session_changes.py
Executable file
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Database migration script for session changes
|
||||
Handles all database schema changes made during this session:
|
||||
1. Adding likes column (if not exists)
|
||||
2. Ensuring description column exists
|
||||
3. Updating any existing records to have default values
|
||||
|
||||
This script is idempotent - can be run multiple times safely.
|
||||
"""
|
||||
|
||||
import sqlite3
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def get_database_path():
|
||||
"""Get the correct database path"""
|
||||
if os.path.exists("pet_pictures.db"):
|
||||
return "pet_pictures.db"
|
||||
elif os.path.exists("app/pet_pictures.db"):
|
||||
return "app/pet_pictures.db"
|
||||
else:
|
||||
return "pet_pictures.db" # Default path
|
||||
|
||||
|
||||
def check_column_exists(cursor, table_name, column_name):
|
||||
"""Check if a column exists in a table"""
|
||||
cursor.execute(f"PRAGMA table_info({table_name})")
|
||||
columns = [column[1] for column in cursor.fetchall()]
|
||||
return column_name in columns
|
||||
|
||||
|
||||
def migrate_database():
|
||||
"""Main migration function"""
|
||||
db_path = get_database_path()
|
||||
print(f"Using database: {db_path}")
|
||||
|
||||
try:
|
||||
# Connect to the database
|
||||
db = sqlite3.connect(db_path)
|
||||
cursor = db.cursor()
|
||||
|
||||
print("Starting database migration...")
|
||||
|
||||
# Check if pet_pictures table exists
|
||||
cursor.execute("""
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name='pet_pictures'
|
||||
""")
|
||||
|
||||
if not cursor.fetchone():
|
||||
print("pet_pictures table doesn't exist. Creating it...")
|
||||
cursor.execute("""
|
||||
CREATE TABLE pet_pictures (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
filename TEXT NOT NULL,
|
||||
subscriber_name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
uploaded_at TIMESTAMP NOT NULL,
|
||||
posted BOOLEAN DEFAULT 0,
|
||||
likes INTEGER DEFAULT 0
|
||||
)
|
||||
""")
|
||||
db.commit()
|
||||
print("✓ Created pet_pictures table with all columns")
|
||||
return
|
||||
|
||||
migrations_applied = 0
|
||||
|
||||
# Migration 1: Add description column if it doesn't exist
|
||||
if not check_column_exists(cursor, 'pet_pictures', 'description'):
|
||||
print("Adding description column...")
|
||||
cursor.execute("ALTER TABLE pet_pictures ADD COLUMN description TEXT")
|
||||
db.commit()
|
||||
print("✓ Added description column")
|
||||
migrations_applied += 1
|
||||
else:
|
||||
print("• Description column already exists")
|
||||
|
||||
# Migration 2: Add likes column if it doesn't exist
|
||||
if not check_column_exists(cursor, 'pet_pictures', 'likes'):
|
||||
print("Adding likes column...")
|
||||
cursor.execute("ALTER TABLE pet_pictures ADD COLUMN likes INTEGER DEFAULT 0")
|
||||
|
||||
# Update existing records to have 0 likes
|
||||
cursor.execute("UPDATE pet_pictures SET likes = 0 WHERE likes IS NULL")
|
||||
db.commit()
|
||||
print("✓ Added likes column and initialized existing records")
|
||||
migrations_applied += 1
|
||||
else:
|
||||
print("• Likes column already exists")
|
||||
|
||||
# Migration 3: Ensure posted column exists and has correct type
|
||||
if not check_column_exists(cursor, 'pet_pictures', 'posted'):
|
||||
print("Adding posted column...")
|
||||
cursor.execute("ALTER TABLE pet_pictures ADD COLUMN posted BOOLEAN DEFAULT 0")
|
||||
db.commit()
|
||||
print("✓ Added posted column")
|
||||
migrations_applied += 1
|
||||
else:
|
||||
print("• Posted column already exists")
|
||||
|
||||
# Migration 4: Clean up any NULL values in critical columns
|
||||
print("Cleaning up NULL values...")
|
||||
cursor.execute("""
|
||||
UPDATE pet_pictures
|
||||
SET likes = 0
|
||||
WHERE likes IS NULL
|
||||
""")
|
||||
|
||||
cursor.execute("""
|
||||
UPDATE pet_pictures
|
||||
SET posted = 0
|
||||
WHERE posted IS NULL
|
||||
""")
|
||||
|
||||
cursor.execute("""
|
||||
UPDATE pet_pictures
|
||||
SET description = ''
|
||||
WHERE description IS NULL
|
||||
""")
|
||||
|
||||
db.commit()
|
||||
print("✓ Cleaned up NULL values")
|
||||
|
||||
# Verify final schema
|
||||
cursor.execute("PRAGMA table_info(pet_pictures)")
|
||||
columns = cursor.fetchall()
|
||||
|
||||
print("\nFinal table schema:")
|
||||
for column in columns:
|
||||
print(f" {column[1]} {column[2]} {'NOT NULL' if column[3] else 'NULL'} {f'DEFAULT {column[4]}' if column[4] else ''}")
|
||||
|
||||
# Get record count
|
||||
cursor.execute("SELECT COUNT(*) FROM pet_pictures")
|
||||
record_count = cursor.fetchone()[0]
|
||||
|
||||
print(f"\nMigration completed successfully!")
|
||||
print(f"Applied {migrations_applied} migrations")
|
||||
print(f"Database contains {record_count} pet pictures")
|
||||
|
||||
# Log migration
|
||||
print(f"Migration completed at: {datetime.now().isoformat()}")
|
||||
|
||||
except sqlite3.Error as e:
|
||||
print(f"❌ Database error occurred: {e}")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"❌ An unexpected error occurred: {e}")
|
||||
sys.exit(1)
|
||||
finally:
|
||||
if 'db' in locals():
|
||||
db.close()
|
||||
|
||||
|
||||
def verify_migration():
|
||||
"""Verify that the migration was successful"""
|
||||
db_path = get_database_path()
|
||||
|
||||
try:
|
||||
db = sqlite3.connect(db_path)
|
||||
cursor = db.cursor()
|
||||
|
||||
# Check all required columns exist
|
||||
required_columns = ['id', 'filename', 'subscriber_name', 'description', 'uploaded_at', 'posted', 'likes']
|
||||
cursor.execute("PRAGMA table_info(pet_pictures)")
|
||||
existing_columns = [column[1] for column in cursor.fetchall()]
|
||||
|
||||
missing_columns = set(required_columns) - set(existing_columns)
|
||||
if missing_columns:
|
||||
print(f"❌ Verification failed: Missing columns: {missing_columns}")
|
||||
return False
|
||||
|
||||
print("✅ Verification successful: All required columns present")
|
||||
return True
|
||||
|
||||
except sqlite3.Error as e:
|
||||
print(f"❌ Verification failed with database error: {e}")
|
||||
return False
|
||||
finally:
|
||||
if 'db' in locals():
|
||||
db.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 60)
|
||||
print("Pet Picture Database Migration Script")
|
||||
print("Session Changes: Adding likes system and ensuring schema consistency")
|
||||
print("=" * 60)
|
||||
|
||||
# Run migration
|
||||
migrate_database()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Verifying migration...")
|
||||
|
||||
# Verify migration
|
||||
if verify_migration():
|
||||
print("🎉 Migration completed successfully!")
|
||||
else:
|
||||
print("⚠️ Migration verification failed")
|
||||
sys.exit(1)
|
||||
|
||||
print("=" * 60)
|
||||
Reference in New Issue
Block a user