From 3f9de1449c9ab8c7ac101a7d60a1f07fd76c38b1 Mon Sep 17 00:00:00 2001 From: "Troll (Hermes Agent)" Date: Wed, 5 Aug 2026 13:42:10 +0000 Subject: [PATCH] Fix 500 on customer revision when revision_history table is missing Deployed databases can persist without the revision_history table, causing /play//revise to crash with sqlite3.OperationalError. - log_revision() now creates the table on the fly if it is missing. - app.py runs init_db() at import time (safe CREATE TABLE IF NOT EXISTS) so new deployments auto-create missing tables on startup. Bump patch version 0.4.0 -> 0.4.1. --- README.md | 2 +- VERSION | 2 +- app.py | 13 +++++++++++++ models.py | 30 ++++++++++++++++++++++-------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c407afe..35e38cb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Theme Song Booth -**Version:** `v0.4.0` +**Version:** `v0.4.1` A Flask web app for a convention booth where visitors request a custom AI-generated theme song, the operator manages the queue, and the final MP3(s) are delivered by email after payment. diff --git a/VERSION b/VERSION index 1d0ba9e..267577d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.0 +0.4.1 diff --git a/app.py b/app.py index 50dd9dc..323b7b3 100644 --- a/app.py +++ b/app.py @@ -1493,3 +1493,16 @@ def init_db_command(): if __name__ == '__main__': # Development-only entry point. Production uses gunicorn (see Dockerfile). app.run(debug=True, host='0.0.0.0') + + +# Ensure the database file and expected tables exist when the app is imported by +# gunicorn in production. init_db() uses CREATE TABLE IF NOT EXISTS, so this is +# safe to run on every startup without wiping data. +with app.app_context(): + try: + init_db() + except Exception: + # If the database path is not yet reachable (e.g. volume not mounted), + # defer to the first request or the explicit init-db command. + import logging + logging.getLogger('app').warning('Startup init_db() failed; database may need manual initialization.', exc_info=True) diff --git a/models.py b/models.py index 6b0d16e..63b6a17 100644 --- a/models.py +++ b/models.py @@ -184,15 +184,29 @@ def delete_request(request_id): def log_revision(request_id, revision_count, note, old_a=None, old_b=None, new_a=None, new_b=None): - """Record a revision event in the revision_history table.""" + """Record a revision event in the revision_history table, creating the table if it is missing.""" db = get_db() - db.execute( - """INSERT INTO revision_history - (request_id, revision_count, note, old_song_a_path, old_song_b_path, new_song_a_path, new_song_b_path) - VALUES (?, ?, ?, ?, ?, ?, ?)""", - (request_id, revision_count, note, old_a, old_b, new_a, new_b) - ) - db.commit() + try: + db.execute( + """INSERT INTO revision_history + (request_id, revision_count, note, old_song_a_path, old_song_b_path, new_song_a_path, new_song_b_path) + VALUES (?, ?, ?, ?, ?, ?, ?)""", + (request_id, revision_count, note, old_a, old_b, new_a, new_b) + ) + db.commit() + except sqlite3.OperationalError as e: + if 'no such table' in str(e): + # Schema drift: table missing. Recreate and retry once. + db.executescript(SCHEMA) + db.execute( + """INSERT INTO revision_history + (request_id, revision_count, note, old_song_a_path, old_song_b_path, new_song_a_path, new_song_b_path) + VALUES (?, ?, ?, ?, ?, ?, ?)""", + (request_id, revision_count, note, old_a, old_b, new_a, new_b) + ) + db.commit() + else: + raise def list_revision_history(request_id):