fix(db): anadir migraciones DDL para columnas extendidas de users, subjects y commissions
This commit is contained in:
+107
-15
@@ -22,21 +22,29 @@ def init_database():
|
||||
|
||||
# 2. Migraciones incrementales seguras para bases de datos existentes
|
||||
if db.engine.url.drivername != 'sqlite':
|
||||
# Columnas extendidas de users
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS preferred_language VARCHAR(10) DEFAULT NULL;
|
||||
"""))
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS theme_preference VARCHAR(10) DEFAULT 'auto' NOT NULL;
|
||||
"""))
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id INTEGER REFERENCES roles(id) ON DELETE SET NULL;
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS first_name VARCHAR(100);
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS last_name VARCHAR(100);
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS phone VARCHAR(50);
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS personal_email VARCHAR(255);
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS address VARCHAR(255);
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS document_type VARCHAR(20) DEFAULT 'DNI';
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS document_number VARCHAR(30);
|
||||
CREATE INDEX IF NOT EXISTS ix_users_document_number ON users (document_number);
|
||||
"""))
|
||||
|
||||
# Columnas extendidas de subjects
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE subjects ADD COLUMN IF NOT EXISTS career_id INTEGER REFERENCES careers(id) ON DELETE SET NULL;
|
||||
"""))
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE subjects ALTER COLUMN code TYPE VARCHAR(50);
|
||||
ALTER TABLE subjects ADD COLUMN IF NOT EXISTS is_short_course BOOLEAN DEFAULT FALSE;
|
||||
"""))
|
||||
|
||||
# Infraestructura: buildings y classrooms
|
||||
db.session.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS buildings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
@@ -49,7 +57,26 @@ def init_database():
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
ALTER TABLE classrooms ADD COLUMN IF NOT EXISTS building_id INTEGER REFERENCES buildings(id) ON DELETE SET NULL;
|
||||
"""))
|
||||
|
||||
# Columnas extendidas de commissions
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS virtual_link VARCHAR(500);
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS grades_closed BOOLEAN DEFAULT FALSE;
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS grades_closed_at TIMESTAMP WITHOUT TIME ZONE;
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS grades_closed_by INTEGER REFERENCES users(id) ON DELETE SET NULL;
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS acta_number VARCHAR(50);
|
||||
"""))
|
||||
|
||||
# Columnas extendidas de reservations
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
||||
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS virtual_link VARCHAR(500);
|
||||
"""))
|
||||
|
||||
# Tablas de soporte: audit_logs
|
||||
db.session.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS audit_logs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
@@ -66,15 +93,8 @@ def init_database():
|
||||
CREATE INDEX IF NOT EXISTS ix_audit_logs_module ON audit_logs (module);
|
||||
CREATE INDEX IF NOT EXISTS ix_audit_logs_created_at ON audit_logs (created_at);
|
||||
"""))
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE classrooms ADD COLUMN IF NOT EXISTS building_id INTEGER REFERENCES buildings(id) ON DELETE SET NULL;
|
||||
"""))
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
||||
"""))
|
||||
db.session.execute(text("""
|
||||
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
||||
"""))
|
||||
|
||||
# Tablas de soporte: student_enrollments
|
||||
db.session.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS student_enrollments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
@@ -89,7 +109,79 @@ def init_database():
|
||||
CREATE INDEX IF NOT EXISTS ix_student_enrollments_student_id ON student_enrollments (student_id);
|
||||
CREATE INDEX IF NOT EXISTS ix_student_enrollments_commission_id ON student_enrollments (commission_id);
|
||||
"""))
|
||||
|
||||
# Tablas de soporte: commission_teachers
|
||||
db.session.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS commission_teachers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
commission_id INTEGER NOT NULL REFERENCES commissions(id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role VARCHAR(50) DEFAULT 'Titular' NOT NULL,
|
||||
is_primary BOOLEAN DEFAULT FALSE NOT NULL,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||
CONSTRAINT uq_commission_teacher UNIQUE (commission_id, user_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_commission_teachers_commission_id ON commission_teachers (commission_id);
|
||||
CREATE INDEX IF NOT EXISTS ix_commission_teachers_user_id ON commission_teachers (user_id);
|
||||
"""))
|
||||
|
||||
# Tablas de soporte: system_settings
|
||||
db.session.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS system_settings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
key VARCHAR(100) UNIQUE NOT NULL,
|
||||
value TEXT,
|
||||
description VARCHAR(255),
|
||||
category VARCHAR(50) DEFAULT 'system',
|
||||
is_encrypted BOOLEAN DEFAULT FALSE,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_system_settings_key ON system_settings (key);
|
||||
"""))
|
||||
|
||||
# Tablas de soporte: moodle_sync_tasks
|
||||
db.session.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS moodle_sync_tasks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
action VARCHAR(50) NOT NULL,
|
||||
entity_type VARCHAR(50) NOT NULL,
|
||||
entity_id VARCHAR(100),
|
||||
payload TEXT NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'PENDING',
|
||||
attempts INTEGER DEFAULT 0,
|
||||
max_attempts INTEGER DEFAULT 5,
|
||||
error_message TEXT,
|
||||
next_retry_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_moodle_sync_tasks_action ON moodle_sync_tasks (action);
|
||||
CREATE INDEX IF NOT EXISTS ix_moodle_sync_tasks_status ON moodle_sync_tasks (status);
|
||||
CREATE INDEX IF NOT EXISTS ix_moodle_sync_tasks_next_retry_at ON moodle_sync_tasks (next_retry_at);
|
||||
"""))
|
||||
db.session.commit()
|
||||
else:
|
||||
try:
|
||||
cursor = db.session.connection().connection.cursor()
|
||||
cursor.execute("PRAGMA table_info(users)")
|
||||
existing_cols = [row[1] for row in cursor.fetchall()]
|
||||
for col_name, col_def in [
|
||||
('preferred_language', 'VARCHAR(10)'),
|
||||
('theme_preference', "VARCHAR(10) DEFAULT 'auto'"),
|
||||
('role_id', 'INTEGER'),
|
||||
('first_name', 'VARCHAR(100)'),
|
||||
('last_name', 'VARCHAR(100)'),
|
||||
('phone', 'VARCHAR(50)'),
|
||||
('personal_email', 'VARCHAR(255)'),
|
||||
('address', 'VARCHAR(255)'),
|
||||
('document_type', "VARCHAR(20) DEFAULT 'DNI'"),
|
||||
('document_number', 'VARCHAR(30)')
|
||||
]:
|
||||
if col_name not in existing_cols:
|
||||
cursor.execute(f"ALTER TABLE users ADD COLUMN {col_name} {col_def}")
|
||||
db.session.commit()
|
||||
except Exception:
|
||||
pass
|
||||
print("[OK] Esquema y tablas actualizadas con éxito.")
|
||||
|
||||
# 3. Crear o sincronizar roles predeterminados y matriz de permisos
|
||||
|
||||
Reference in New Issue
Block a user