mirror of
https://github.com/tmdinosaurcenter/kiosk-guestbook.git
synced 2026-06-03 23:09:35 -06:00
refactor: replace init_db with lightweight schema migration system
- Add MIGRATIONS list — each entry is a list of SQL statements for that schema version; append new lists to add future migrations, never modify existing ones - Add schema_version table to track applied migrations - migrate_db() runs on startup and applies any pending versions automatically; safe to run against existing DBs (v1 uses CREATE IF NOT EXISTS so it no-ops on the existing table/indexes)
This commit is contained in:
@@ -51,12 +51,12 @@ def contains_banned_words(text):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def init_db():
|
# Each entry is a list of SQL statements for that schema version.
|
||||||
# TODO: No schema versioning — adding columns in the future requires manual DB updates. Consider a migration tool (e.g. Alembic).
|
# To add a column or index in the future, append a new list — never modify existing entries.
|
||||||
conn = sqlite3.connect(DATABASE)
|
MIGRATIONS = [
|
||||||
c = conn.cursor()
|
# v1 — initial schema
|
||||||
c.execute('''
|
[
|
||||||
CREATE TABLE IF NOT EXISTS guests (
|
'''CREATE TABLE IF NOT EXISTS guests (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
first_name TEXT NOT NULL,
|
first_name TEXT NOT NULL,
|
||||||
last_name TEXT NOT NULL,
|
last_name TEXT NOT NULL,
|
||||||
@@ -65,13 +65,40 @@ def init_db():
|
|||||||
comment TEXT,
|
comment TEXT,
|
||||||
newsletter_opt_in BOOLEAN DEFAULT 1,
|
newsletter_opt_in BOOLEAN DEFAULT 1,
|
||||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
)
|
)''',
|
||||||
''')
|
'CREATE INDEX IF NOT EXISTS idx_guests_id ON guests (id DESC)',
|
||||||
c.execute('CREATE INDEX IF NOT EXISTS idx_guests_id ON guests (id DESC)')
|
'CREATE INDEX IF NOT EXISTS idx_guests_email ON guests (email)',
|
||||||
c.execute('CREATE INDEX IF NOT EXISTS idx_guests_email ON guests (email)')
|
],
|
||||||
conn.commit()
|
]
|
||||||
|
|
||||||
|
def migrate_db():
|
||||||
|
conn = sqlite3.connect(DATABASE)
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
# Bootstrap the version table and seed it at 0 if empty
|
||||||
|
c.execute('CREATE TABLE IF NOT EXISTS schema_version (version INTEGER NOT NULL)')
|
||||||
|
if c.execute('SELECT COUNT(*) FROM schema_version').fetchone()[0] == 0:
|
||||||
|
c.execute('INSERT INTO schema_version VALUES (0)')
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
current = c.execute('SELECT version FROM schema_version').fetchone()[0]
|
||||||
|
pending = MIGRATIONS[current:]
|
||||||
|
|
||||||
|
if not pending:
|
||||||
|
logger.info("Database schema is up to date at v%d.", current)
|
||||||
|
conn.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
for statements in pending:
|
||||||
|
current += 1
|
||||||
|
logger.info("Applying migration v%d...", current)
|
||||||
|
for sql in statements:
|
||||||
|
c.execute(sql)
|
||||||
|
c.execute('UPDATE schema_version SET version = ?', (current,))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
logger.info("Database migrated to v%d.", current)
|
||||||
conn.close()
|
conn.close()
|
||||||
logger.info("Database initialized.")
|
|
||||||
|
|
||||||
def is_valid_email(email):
|
def is_valid_email(email):
|
||||||
try:
|
try:
|
||||||
@@ -81,7 +108,7 @@ def is_valid_email(email):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
init_db()
|
migrate_db()
|
||||||
|
|
||||||
@app.route('/', methods=['GET', 'POST'])
|
@app.route('/', methods=['GET', 'POST'])
|
||||||
@limiter.limit("5 per minute", methods=["POST"])
|
@limiter.limit("5 per minute", methods=["POST"])
|
||||||
@@ -186,6 +213,6 @@ def api_guests():
|
|||||||
return jsonify(guests)
|
return jsonify(guests)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
init_db()
|
migrate_db()
|
||||||
logger.info("Starting development server at http://0.0.0.0:8000")
|
logger.info("Starting development server at http://0.0.0.0:8000")
|
||||||
app.run(host='0.0.0.0', port=8000)
|
app.run(host='0.0.0.0', port=8000)
|
||||||
|
|||||||
Reference in New Issue
Block a user