"""启动时补齐新增列(已有库无需手工迁移)。""" from sqlalchemy import inspect, text from database import engine def run_migrations() -> None: insp = inspect(engine) with engine.begin() as conn: if insp.has_table("words"): cols = {c["name"] for c in insp.get_columns("words")} if "total_train_seconds" not in cols: conn.execute( text( "ALTER TABLE words ADD COLUMN total_train_seconds " "INTEGER NOT NULL DEFAULT 0" ) ) if "train_count" not in cols: conn.execute( text("ALTER TABLE words ADD COLUMN train_count INTEGER NOT NULL DEFAULT 0") ) if insp.has_table("quiz_records"): cols = {c["name"] for c in insp.get_columns("quiz_records")} if "duration_seconds" not in cols: conn.execute( text( "ALTER TABLE quiz_records ADD COLUMN duration_seconds " "INTEGER NOT NULL DEFAULT 0" ) ) if insp.has_table("user_settings"): cols = {c["name"] for c in insp.get_columns("user_settings")} if "active_book_id" not in cols: conn.execute(text("ALTER TABLE user_settings ADD COLUMN active_book_id INTEGER")) if not insp.has_table("user_book_settings"): conn.execute( text( """ CREATE TABLE user_book_settings ( id INTEGER PRIMARY KEY AUTO_INCREMENT, user_id INTEGER NOT NULL, book_id INTEGER NOT NULL, daily_target INTEGER NOT NULL DEFAULT 12, master_required_count INTEGER NOT NULL DEFAULT 3, weak_wrong_threshold INTEGER NOT NULL DEFAULT 2, CONSTRAINT uq_user_book_settings UNIQUE (user_id, book_id), FOREIGN KEY(user_id) REFERENCES users (id), FOREIGN KEY(book_id) REFERENCES word_books (id) ) """ ) ) if insp.has_table("words"): cols = {c["name"] for c in insp.get_columns("words")} if "book_id" not in cols: conn.execute( text("ALTER TABLE words ADD COLUMN book_id INTEGER NOT NULL DEFAULT 0") ) conn.execute(text("CREATE INDEX ix_words_book_id ON words (book_id)")) if "book_entry_id" not in cols: conn.execute(text("ALTER TABLE words ADD COLUMN book_entry_id INTEGER")) if insp.has_table("words") and insp.has_table("quiz_records"): conn.execute( text( """ UPDATE words w SET train_count = ( SELECT COUNT(*) FROM quiz_records q WHERE q.word_id = w.id ), total_train_seconds = ( SELECT COALESCE(SUM(duration_seconds), 0) FROM quiz_records q WHERE q.word_id = w.id ) WHERE train_count = 0 AND EXISTS ( SELECT 1 FROM quiz_records q WHERE q.word_id = w.id ) """ ) )