81 lines
No EOL
2.7 KiB
Python
81 lines
No EOL
2.7 KiB
Python
"""
|
|
Automatic database migrations system
|
|
"""
|
|
import logging
|
|
from sqlalchemy import inspect
|
|
from .. import db
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class Migration:
|
|
"""Base migration class"""
|
|
# Higher version numbers run later
|
|
version = 0
|
|
description = "Base migration"
|
|
|
|
def should_run(self, inspector):
|
|
"""Determine if this migration should run"""
|
|
return True
|
|
|
|
def run(self):
|
|
"""Execute the migration"""
|
|
raise NotImplementedError
|
|
|
|
class AddFolderIdToFiles(Migration):
|
|
"""Add folder_id column to files table"""
|
|
version = 1
|
|
description = "Add folder_id column to files table"
|
|
|
|
def should_run(self, inspector):
|
|
"""Check if folder_id column exists in files table"""
|
|
if 'files' not in inspector.get_table_names():
|
|
return False
|
|
|
|
columns = [col['name'] for col in inspector.get_columns('files')]
|
|
return 'folder_id' not in columns
|
|
|
|
def run(self):
|
|
"""Add the folder_id column and foreign key constraint"""
|
|
try:
|
|
db.engine.execute('ALTER TABLE files ADD COLUMN folder_id INTEGER;')
|
|
db.engine.execute('ALTER TABLE files ADD CONSTRAINT fk_files_folder_id FOREIGN KEY (folder_id) REFERENCES folders (id);')
|
|
logger.info("Added folder_id column to files table")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Error adding folder_id column: {str(e)}")
|
|
return False
|
|
|
|
# Add all migrations here
|
|
MIGRATIONS = [
|
|
AddFolderIdToFiles(),
|
|
# Remove the Share table migration since we're not using it
|
|
]
|
|
|
|
def run_migrations():
|
|
"""Run all pending migrations"""
|
|
logger.info("Checking for pending database migrations...")
|
|
inspector = inspect(db.engine)
|
|
|
|
# Sort migrations by version
|
|
pending_migrations = sorted([m for m in MIGRATIONS if m.should_run(inspector)],
|
|
key=lambda m: m.version)
|
|
|
|
if not pending_migrations:
|
|
logger.info("No pending migrations found.")
|
|
return
|
|
|
|
logger.info(f"Found {len(pending_migrations)} pending migrations.")
|
|
|
|
success_count = 0
|
|
for migration in pending_migrations:
|
|
logger.info(f"Running migration {migration.version}: {migration.description}")
|
|
try:
|
|
success = migration.run()
|
|
if success:
|
|
success_count += 1
|
|
else:
|
|
logger.warning(f"Migration {migration.version} reported failure")
|
|
except Exception as e:
|
|
logger.error(f"Error in migration {migration.version}: {str(e)}")
|
|
|
|
logger.info(f"Migration complete. {success_count}/{len(pending_migrations)} migrations successful.") |