fix: prevent UNIQUE constraint race with gunicorn multi-worker

Use INSERT OR IGNORE instead of SELECT-then-INSERT for
default admin user creation, avoiding the race condition
when multiple gunicorn workers initialize simultaneously.
This commit is contained in:
Yuyao Huang 2026-05-09 10:19:58 +08:00
parent 2629e8f2cd
commit 2a3482c2c0
2 changed files with 11 additions and 11 deletions

View File

@ -80,6 +80,8 @@ uv add gunicorn
uv run gunicorn -w 4 -b 0.0.0.0:5000 app:app uv run gunicorn -w 4 -b 0.0.0.0:5000 app:app
``` ```
> **Note:** The `-b` flag is required because gunicorn is a separate WSGI server and does not read Flask's `config.py`. The values in `config.py` (`HOST`, `PORT`) only apply to Flask's built-in dev server (`app.run()`).
## Project Structure ## Project Structure
``` ```

View File

@ -86,16 +86,14 @@ def init_db():
conn.commit() conn.commit()
import bcrypt import bcrypt
cur = conn.execute("SELECT COUNT(*) FROM users WHERE role = 'admin'") password_hash = bcrypt.hashpw(
if cur.fetchone()[0] == 0: config.DEFAULT_ADMIN_PASSWORD.encode("utf-8"),
password_hash = bcrypt.hashpw( bcrypt.gensalt()
config.DEFAULT_ADMIN_PASSWORD.encode("utf-8"), ).decode("utf-8")
bcrypt.gensalt() conn.execute(
).decode("utf-8") "INSERT OR IGNORE INTO users (username, password_hash, role, max_goals) VALUES (?, ?, ?, ?)",
conn.execute( (config.DEFAULT_ADMIN_USERNAME, password_hash, "admin", 100)
"INSERT INTO users (username, password_hash, role, max_goals) VALUES (?, ?, ?, ?)", )
(config.DEFAULT_ADMIN_USERNAME, password_hash, "admin", 100) conn.commit()
)
conn.commit()
finally: finally:
conn.close() conn.close()