#!/usr/bin/env python3.11 """ Datenbank-Migrationsskript für MYP Platform Dieses Skript führt notwendige Änderungen an der Datenbankstruktur durch, um sie mit den neuesten Modellen kompatibel zu machen. """ import sqlite3 import os from datetime import datetime from config.settings import DATABASE_PATH, ensure_database_directory def migrate_database(): """Führt alle notwendigen Datenbankmigrationen durch.""" ensure_database_directory() if not os.path.exists(DATABASE_PATH): print("Datenbank existiert nicht. Führe init_db.py aus, um sie zu erstellen.") return False conn = sqlite3.connect(DATABASE_PATH) cursor = conn.cursor() print("Starte Datenbankmigration...") try: # Migration 1: Füge username-Feld zu users-Tabelle hinzu try: cursor.execute("ALTER TABLE users ADD COLUMN username VARCHAR(100)") print("✓ Username-Feld zur users-Tabelle hinzugefügt") except sqlite3.OperationalError as e: if "duplicate column name" in str(e).lower(): print("✓ Username-Feld bereits vorhanden") else: raise e # Migration 2: Füge active-Feld zu users-Tabelle hinzu try: cursor.execute("ALTER TABLE users ADD COLUMN active BOOLEAN DEFAULT 1") print("✓ Active-Feld zur users-Tabelle hinzugefügt") except sqlite3.OperationalError as e: if "duplicate column name" in str(e).lower(): print("✓ Active-Feld bereits vorhanden") else: raise e # Migration 3: Setze username für bestehende Benutzer cursor.execute("SELECT id, email, username FROM users WHERE username IS NULL OR username = ''") users_without_username = cursor.fetchall() for user_id, email, username in users_without_username: if not username: # Generiere username aus email (Teil vor @) new_username = email.split('@')[0] if '@' in email else f"user_{user_id}" cursor.execute("UPDATE users SET username = ? WHERE id = ?", (new_username, user_id)) print(f"✓ Username '{new_username}' für Benutzer {email} gesetzt") # Migration 4: Prüfe und korrigiere Job-Tabelle falls nötig try: # Prüfe ob die Tabelle die neuen Felder hat cursor.execute("PRAGMA table_info(jobs)") columns = [row[1] for row in cursor.fetchall()] if 'duration_minutes' not in columns: cursor.execute("ALTER TABLE jobs ADD COLUMN duration_minutes INTEGER") print("✓ Duration_minutes-Feld zur jobs-Tabelle hinzugefügt") # Setze Standardwerte für bestehende Jobs (60 Minuten) cursor.execute("UPDATE jobs SET duration_minutes = 60 WHERE duration_minutes IS NULL") print("✓ Standardwerte für duration_minutes gesetzt") # Prüfe ob title zu name umbenannt werden muss if 'title' in columns and 'name' not in columns: # SQLite unterstützt kein direktes Umbenennen von Spalten # Wir müssen die Tabelle neu erstellen print("⚠ Konvertierung von 'title' zu 'name' in jobs-Tabelle...") # Backup der Daten cursor.execute(""" CREATE TABLE jobs_backup AS SELECT * FROM jobs """) # Lösche alte Tabelle cursor.execute("DROP TABLE jobs") # Erstelle neue Tabelle mit korrekter Struktur cursor.execute(""" CREATE TABLE jobs ( id INTEGER PRIMARY KEY, name VARCHAR(200) NOT NULL, description VARCHAR(500), user_id INTEGER NOT NULL, printer_id INTEGER NOT NULL, start_at DATETIME, end_at DATETIME, actual_end_time DATETIME, status VARCHAR(20) DEFAULT 'scheduled', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, notes VARCHAR(500), material_used FLOAT, file_path VARCHAR(500), owner_id INTEGER, duration_minutes INTEGER NOT NULL DEFAULT 60, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (printer_id) REFERENCES printers(id), FOREIGN KEY (owner_id) REFERENCES users(id) ) """) # Daten zurückkopieren (title -> name) cursor.execute(""" INSERT INTO jobs ( id, name, description, user_id, printer_id, start_at, end_at, actual_end_time, status, created_at, notes, material_used, file_path, owner_id, duration_minutes ) SELECT id, title, description, user_id, printer_id, start_at, end_at, actual_end_time, status, created_at, notes, material_used, file_path, owner_id, COALESCE(duration_minutes, 60) FROM jobs_backup """) # Backup-Tabelle löschen cursor.execute("DROP TABLE jobs_backup") print("✓ Jobs-Tabelle erfolgreich konvertiert") except sqlite3.OperationalError as e: print(f"⚠ Fehler bei Job-Tabellen-Migration: {e}") # Änderungen speichern conn.commit() print("\n✅ Datenbankmigration erfolgreich abgeschlossen!") return True except Exception as e: print(f"\n❌ Fehler bei der Migration: {e}") conn.rollback() return False finally: conn.close() if __name__ == "__main__": success = migrate_database() if success: print("\nDie Datenbank wurde erfolgreich migriert.") print("Sie können nun die Anwendung starten: python3.11 app.py") else: print("\nMigration fehlgeschlagen. Bitte überprüfen Sie die Fehlermeldungen.")