86 lines
3.7 KiB
Python
86 lines
3.7 KiB
Python
from sqlalchemy import inspect, text
|
|
|
|
from app.core.config import settings
|
|
from app.core.database import engine
|
|
|
|
|
|
def run_migrations() -> None:
|
|
"""Apply lightweight schema updates for existing databases."""
|
|
inspector = inspect(engine)
|
|
tables = set(inspector.get_table_names())
|
|
if "students" not in tables:
|
|
return
|
|
|
|
columns = {col["name"] for col in inspector.get_columns("students")}
|
|
if "school_level" not in columns:
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"ALTER TABLE students ADD COLUMN school_level VARCHAR(32) "
|
|
"NOT NULL DEFAULT 'junior_high'"
|
|
)
|
|
)
|
|
|
|
if "users" in tables:
|
|
user_columns = {col["name"] for col in inspector.get_columns("users")}
|
|
if "is_superuser" not in user_columns:
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text("ALTER TABLE users ADD COLUMN is_superuser BOOLEAN NOT NULL DEFAULT FALSE")
|
|
)
|
|
conn.execute(
|
|
text(
|
|
f"UPDATE users SET is_superuser = TRUE "
|
|
f"WHERE username = '{settings.ADMIN_DEFAULT_USERNAME}'"
|
|
)
|
|
)
|
|
|
|
if "wrong_questions" in tables:
|
|
wq_columns = {col["name"] for col in inspector.get_columns("wrong_questions")}
|
|
if "category" not in wq_columns:
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"ALTER TABLE wrong_questions ADD COLUMN category VARCHAR(32) "
|
|
"NOT NULL DEFAULT 'regular'"
|
|
)
|
|
)
|
|
|
|
if "system_settings" in tables:
|
|
ss_columns = {col["name"] for col in inspector.get_columns("system_settings")}
|
|
alters: list[str] = []
|
|
if "ai_provider" not in ss_columns:
|
|
alters.append("ADD COLUMN ai_provider VARCHAR(16) NOT NULL DEFAULT 'ollama'")
|
|
if "ollama_base_url" not in ss_columns:
|
|
alters.append("ADD COLUMN ollama_base_url VARCHAR(256)")
|
|
if "ollama_model" not in ss_columns:
|
|
alters.append("ADD COLUMN ollama_model VARCHAR(128)")
|
|
if "openai_base_url" not in ss_columns:
|
|
alters.append("ADD COLUMN openai_base_url VARCHAR(256)")
|
|
if "openai_model" not in ss_columns:
|
|
alters.append("ADD COLUMN openai_model VARCHAR(128)")
|
|
if "openai_api_key" not in ss_columns:
|
|
alters.append("ADD COLUMN openai_api_key VARCHAR(512)")
|
|
if "ocr_service_url" not in ss_columns:
|
|
alters.append("ADD COLUMN ocr_service_url VARCHAR(256)")
|
|
if alters:
|
|
with engine.begin() as conn:
|
|
for clause in alters:
|
|
conn.execute(text(f"ALTER TABLE system_settings {clause}"))
|
|
|
|
if "wrong_questions" in tables:
|
|
wq_columns = {col["name"] for col in inspector.get_columns("wrong_questions")}
|
|
wq_alters: list[str] = []
|
|
if "solution_approach" not in wq_columns:
|
|
wq_alters.append("ADD COLUMN solution_approach TEXT")
|
|
if "mark_regions_json" not in wq_columns:
|
|
wq_alters.append("ADD COLUMN mark_regions_json TEXT")
|
|
if "annotated_image_path" not in wq_columns:
|
|
wq_alters.append("ADD COLUMN annotated_image_path VARCHAR(512)")
|
|
if "error_message" not in wq_columns:
|
|
wq_alters.append("ADD COLUMN error_message TEXT")
|
|
if wq_alters:
|
|
with engine.begin() as conn:
|
|
for clause in wq_alters:
|
|
conn.execute(text(f"ALTER TABLE wrong_questions {clause}"))
|