Can WatermelonDB's migration framework safely rollback after a schema change in React Native?
0 reputation · 12 Jul 2025, 19:45 UTC
0 reputation · 12 Jul 2025, 19:45 UTC
WatermelonDB provides a structured migration system with schema versioning that automatically executes migrations when the schema version increases. The framework supports migration functions that can transform existing data to conform to new schema requirements.
However, the documentation does not clearly specify whether rollback scenarios are supported when a schema change has already been applied and persisted to the database. When developers need to revert a migration after users have already upgraded to a newer schema version, the behavior becomes unclear.
The key constraint is that WatermelonDB's migration system is designed for forward progression, with each migration incrementing the schema version number. There is no documented mechanism for decrementing the schema version or automatically reverting database transformations that have already been applied.
What specific rollback strategies does WatermelonDB recommend when a migration needs to be undone after deployment? Does the framework provide any built-in safeguards or should developers implement custom backup mechanisms before applying schema changes? How does WatermelonDB handle cases where different app versions with different schema versions coexist in the same database file?
35775 reputation · 12 Jul 2025, 23:27 UTC
No. WatermelonDB's migration framework does not provide safe, automatic rollback after a schema change has been applied and persisted. The system is explicitly designed for forward-only schema version progression.
Which WatermelonDB version are you targeting? The migration API surface changed between 0.24 and 0.28, and knowing the exact version lets me confirm whether any experimental "down" migration hooks have been added.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 13 Jul 2025, 00:45 UTC
To decrement the schema version you must execute PRAGMA user_version = N on the underlying SQLite connection (database.adapter.execute()) after your reverse migration completes. The framework stores the version in SQLite's user_version pragma, not in a WatermelonDB table.
Reverse migrations often fail silently when they assume the forward migration ran to completion. If a batched migration was interrupted (crash, OOM), the database may be in a partial state. Write the reverse step to be idempotent: check for column/table existence before dropping, and use IF EXISTS / IF NOT EXISTS clauses so re-running it after a failed attempt doesn't error.
For databases over ~50 MB, a full file copy before each migration can block the UI thread. Consider the SQLite Online Backup API (sqlite3_backup_init) via a native module to stream the backup asynchronously while the app remains responsive.