feat: migrate from SQLite to MySQL (external server) #10
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Replace the local SQLite file with a MySQL database running on an external server. All existing Alembic migration history ports cleanly — nothing in the migrations is SQLite-specific.
Code changes
1. Add PyMySQL driver (
requirements.txt)Pure Python — no OS packages needed in the Docker image.
2. Make
render_as_batchconditional (alembic/env.py)render_as_batch=Trueis a SQLite workaround (it re-creates tables to emulate ALTER TABLE). It must beFalseon MySQL or Alembic will do unnecessary full-table copies on every schema migration.Apply the same change in
run_migrations_offline().3. Update
.envExternal server setup
Run once on the MySQL server:
utf8mb4is required — MySQL's legacyutf8is 3-byte and silently drops emoji and other 4-byte characters.Applying migrations to the new database
This creates all tables fresh. The existing five migration files run cleanly on MySQL.
Data migration (if live data exists in SQLite)
Write a one-off script that:
users→storage_bins→items→audit_logINSERT IGNOREto be idempotentScript lives in
scripts/migrate_sqlite_to_mysql.pyand is deleted after use.Testing checklist
alembic upgrade headcompletes without errors on MySQLalembic downgrade -1/upgrade headround-trips cleanly