162 lines
6.9 KiB
Python
162 lines
6.9 KiB
Python
#!/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 3.5: Füge last_login-Feld zu users-Tabelle hinzu
|
|
try:
|
|
cursor.execute("ALTER TABLE users ADD COLUMN last_login DATETIME")
|
|
print("✓ Last_login-Feld zur users-Tabelle hinzugefügt")
|
|
except sqlite3.OperationalError as e:
|
|
if "duplicate column name" in str(e).lower():
|
|
print("✓ Last_login-Feld bereits vorhanden")
|
|
else:
|
|
raise e
|
|
|
|
# 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.") |