#!/usr/bin/env python # -*- coding: utf-8 -*- """ Script di migrazione database: Rimozione FK da LogAggiornamenti """ import sqlite3 import shutil from datetime import datetime from pathlib import Path # Paths DB_PATH = Path(__file__).parent.parent / 'mediatrack.db' BACKUP_DIR = Path(__file__).parent.parent / 'backups' MIGRATION_SQL = Path(__file__).parent / 'remove_logeventi_fk.sql' def create_backup(): """Crea backup del database prima della migrazione""" BACKUP_DIR.mkdir(exist_ok=True) timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') backup_path = BACKUP_DIR / f'mediatrack_pre_fk_removal_{timestamp}.db' print(f"[BACKUP] Creazione backup: {backup_path}") shutil.copy2(DB_PATH, backup_path) print(f"[OK] Backup creato: {backup_path.stat().st_size / 1024:.1f} KB") return backup_path def run_migration(): """Esegue la migrazione SQL""" print(f"\n[MIGRATION] Esecuzione migrazione da: {MIGRATION_SQL}") # Leggi SQL with open(MIGRATION_SQL, 'r', encoding='utf-8') as f: migration_sql = f.read() # Connetti al database conn = sqlite3.connect(DB_PATH) conn.execute("PRAGMA foreign_keys = OFF") # Disabilita FK temporaneamente cur = conn.cursor() try: # Esegui migration cur.executescript(migration_sql) print("[OK] Migration SQL eseguita con successo") # Verifica risultato cur.execute("SELECT COUNT(*) FROM LogAggiornamenti") count = cur.fetchone()[0] print(f"[INFO] Eventi nella nuova tabella: {count}") # Verifica schema - controlla le FK effettive (non i commenti) cur.execute("PRAGMA foreign_key_list('LogAggiornamenti')") fks = cur.fetchall() # Cerca FK verso AnagraficaMedia fk_to_anagrafica = [fk for fk in fks if fk[2] == 'AnagraficaMedia'] if fk_to_anagrafica: raise Exception(f"[ERRORE] FK verso AnagraficaMedia ancora presente! {fk_to_anagrafica}") else: print("[OK] FK verso AnagraficaMedia rimossa correttamente") print(f"[INFO] FK rimanenti: {len(fks)} (solo verso TipiEvento)") # Verifica indici cur.execute("SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='LogAggiornamenti'") indexes = [row[0] for row in cur.fetchall()] print(f"[INFO] Indici creati: {len(indexes)} ({', '.join(indexes)})") conn.commit() print("\n[SUCCESSO] MIGRATION COMPLETATA CON SUCCESSO!") return True except Exception as e: conn.rollback() print(f"\n[ERRORE] ERRORE durante migration: {e}") print("[ATTENZIONE] Database rollback eseguito - nessuna modifica applicata") return False finally: conn.execute("PRAGMA foreign_keys = ON") # Riabilita FK conn.close() def verify_migration(): """Verifica che la migrazione sia andata a buon fine""" print("\n[VERIFICA] Verifica post-migrazione...") conn = sqlite3.connect(DB_PATH) cur = conn.cursor() # Test: Prova a inserire un evento con ID Gemma fake try: cur.execute(""" INSERT INTO LogAggiornamenti (id_media_fk, id_tipo_evento_fk, data_evento, note) VALUES ('G_TEST_MIGRATION', 1, date('now'), 'Test migration') """) # Recupera cur.execute("SELECT id_aggiornamento, id_media_fk FROM LogAggiornamenti WHERE note = 'Test migration'") result = cur.fetchone() if result: print(f"[OK] Test insert Gemma ID riuscito: {result[0]} -> {result[1]}") # Cleanup cur.execute("DELETE FROM LogAggiornamenti WHERE note = 'Test migration'") conn.commit() print("[OK] Test cleanup completato") return True else: print("[ERRORE] Test insert fallito: record non trovato") return False except sqlite3.IntegrityError as e: print(f"[ERRORE] Test fallito: FK constraint ancora attivo! {e}") conn.rollback() return False finally: conn.close() if __name__ == '__main__': print("=" * 70) print("MIGRATION: Rimozione Foreign Key da LogAggiornamenti") print("=" * 70) print("\n[INFO] Questa migration permettera' di salvare eventi per:") print(" - Prodotti MediaTrack (es: FILM-123)") print(" - Prodotti Gemma (es: G_60558)") print(" - Qualsiasi altro prodotto futuro") print() # Conferma response = input("[ATTENZIONE] Vuoi procedere? (s/n): ").strip().lower() if response != 's': print("[ANNULLATO] Migration annullata dall'utente") exit(0) # Backup backup_path = create_backup() # Migration success = run_migration() if success: # Verifica if verify_migration(): print("\n" + "=" * 70) print("[SUCCESSO] MIGRATION COMPLETATA E VERIFICATA!") print("=" * 70) print(f"\n[BACKUP] Backup disponibile: {backup_path}") print("\n[OK] Ora puoi creare eventi per prodotti Gemma senza doverli importare!") else: print("\n[ATTENZIONE] Migration completata ma verifica fallita") print(f"[BACKUP] Backup disponibile: {backup_path}") else: print(f"\n[ERRORE] Migration fallita - ripristina da backup se necessario: {backup_path}")