3 ms·
Well if you don't mind rewriting tables, just create a table in the new structure, insert data from the old table to the new one, drop the old table, and rename
by PetahNZ 8y ago
Well if you don't mind rewriting tables, just create a table in the new structure, insert data from the old table to the new one, drop the old table, and rename the new table.
- silvestrov 8y agoThat’s not enough because it ignores all foreign key constraints.
- ifdefdebug 8y agoLock db exclusively, disable foreign key checking, rebuild and replace table, reconfigure foreign keys (they are gone after delete and rename), and everything should be fine.
- rypskar 8y agoOne problem is that you then might need a special case for SQLite in migrations which can lead to different db schemas in tests and production
- ngrilly 8y agoUse the same database for test and production. Nowadays, it is really easy to install PostgreSQL or MySQL locally or in your test environment. SQLite is great, but not for replacing PostgreSQL or MySQL during tests.
- ngrilly 8y agoAny idea on how to do this without blocking writes when SQLite is embedded in a server process?
- teraflop 8y agoCreate new empty table, set up trigger on old table to copy across any inserted/updated rows, backfill the remaining rows incrementally, and finally use ALTER TABLE to atomically replace the old table with the new one.
- ngrilly 8y agoYou're right, it should work! When you wrote "backfill the remaining rows incrementally", did you mean having some background process or thread that reads a batch of rows from the old table (for example a few thousands of row), then inserts them in the new table, then commits, and keep doing this until all rows are copied? This way, other writers will be blocked only for the duration of each incremental transaction and will have an opportunity to lock the database for themselves between two batches? Do you have experience doing this on production servers?