Open dusty-phillips opened 3 years ago
Yes, migrations needs to be server side for dexie cloud. And they need to be per-object so they can run on demand when an old client syncs. I designed a solution for this some time ago and it will go into dexie cloud at some point. For now, dexie cloud does not handle migrations - and it's a limitation in need of documenting.
Hi @dfahlander, wanted to circle back on this as you are approaching release… and so am I. I have a rather tricky db migration I need to queue up and wondered if you have more concrete thoughts or plans yet.
Hi! Yes, everything is on place: API:s, management app and the service. I'm just trying to get dexie 4.0 into stable since Dexie Cloud depends on it and we're working on the public message, website updates and newsletter.
Regarding upgrade - it needs to be done server side. The best way right now is to use the CLI to export your database to a JSON file, create a node script that migrates it and then import it back to a new database where you can test that the migrated data looks good.
Export your entire database
npx dexie-cloud export exportfile.json
Migrate the JSON file
node yourMigration.js < exportfile.json > upgradedDB.json
Import it back to a new DB
npx dexie-cloud create
npx dexie-cloud import exportfile.json
Let me know if this would work in your case
Should work in this case since my users aren’t very active, but if they wrote to the db while the migration was happening I would have a problem, right? I guess that can be mitigated with a dual read strategy for some period of time.
I previously had some client side infrastructure that effectively did a “migrate on read” strategy but it was too slow because it never knew if a migration was necessary so it had to check each time. So I can imagine a solution where you store the db version on all server stored objects, and when you read an object from the server you check the version and perform the versioned migration client side of it needs updating.
Thought about this some more and realized that because I am using a pwa, I have no guarantee that the client has updated to the latest client code, so I need to guarantee backwards compatibility even for new objects sent to the server after I migrate.
Just fubar'd my db kind of on purpose (I wanted to see what happened so I could report). Here's what I did
.version()
of the db with a (unindexed) field that contained an object as content.version()
of the db that changed that field's type to a string.upgrade()
function on the new version that iterated all the objects and converted them to strings.version()
and.upgrade()
on load.upgrade()
ran successfully before theold
objects were synced into the db.I don't know that this is a generically solvable problem in a cloud sync world. I think the only realistic solution is to have two fields on the model (one for the old object, one for the new string) and have client code dual read for the foreseeable future (if so, this pattern is worth documenting somewhere).
Couple other ideas:
migrate
function toStore
that knows how to map one version of an object in a table to it's later iteration and dexie runs it for each object as it gets synced in; that would require some interesting per-object versioning.