docs/migration-storage.html
On this page
The storage migration plugin can be used to migrate all data from one existing RxStorage into another. This is useful when:
The storage migration drops deleted documents and filters them out during the migration.
Do never change the schema while doing a storage migration
When you migrate between storages, you might want to change the schema in the same process. You should never do that because it will lead to problems afterwards and might make your database unusable.
When you also want to change your schema, first run the storage migration and afterwards run a normal schema migration.
Lets say you want to migrate from LocalStorage RxStorage to the IndexedDB RxStorage.
import { migrateStorage } from 'rxdb/plugins/migration-storage';
import { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';
import { getRxStorageLocalstorage } from 'rxdb-old/plugins/storage-localstorage';
// create the new RxDatabase
const db = await createRxDatabase({
name: dbLocation,
storage: getRxStorageIndexedDB(),
multiInstance: false
});
await migrateStorage({
database: db as any,
/**
* Name of the old database,
* using the storage migration requires that the
* new database has a different name.
*/
oldDatabaseName: 'myOldDatabaseName',
oldStorage: getRxStorageLocalstorage(), // RxStorage of the old database
batchSize: 500, // batch size
// true: migrate all collections in parallel
// false (default): migrate in serial
parallel: false,
afterMigrateBatch: (input: AfterMigrateBatchHandlerInput) => {
console.log('storage migration: batch processed');
}
});
note
Only collections that exist in the new database at the time you call migrateStorage() will have their data migrated.
['users', 'posts', 'comments'] but your new database only defines ['users', 'posts'], then only users and posts data will be migrated.This allows you to selectively migrate only certain collections if desired, by choosing which collections to define before invoking migrateStorage().
To migrate from a previous RxDB major version, you have to install the 'old' RxDB in the package.json
{
"dependencies": {
"rxdb-old": "npm:[email protected]",
}
}
Then you can run the migration by providing the old storage:
/* ... */
import { migrateStorage } from 'rxdb/plugins/migration-storage';
// import from the old RxDB version
import {
getRxStorageLocalstorage
} from 'rxdb-old/plugins/storage-localstorage';
await migrateStorage({
database: db as any,
/**
* Name of the old database,
* using the storage migration requires that the
* new database has a different name.
*/
oldDatabaseName: 'myOldDatabaseName',
oldStorage: getRxStorageLocalstorage(), // RxStorage of the old database
batchSize: 500, // batch size
parallel: false,
afterMigrateBatch: (input: AfterMigrateBatchHandlerInput) => {
console.log('storage migration: batch processed');
}
});
/* ... */
RxDB Premium has a check in place that ensures that you do not accidentally use the wrong RxDB core and 👑 Premium version together which could break your database state. This can be a problem during migrations where you have multiple versions of RxDB in use and it will throw the error Version mismatch detected. You can disable that check by importing and running the disableVersionCheck() function from RxDB Premium.
// RxDB Premium v15 or newer:
import {
disableVersionCheck
} from 'rxdb-premium-old/plugins/shared';
disableVersionCheck();
// RxDB Premium v14:
// for esm
import {
disableVersionCheck
} from 'rxdb-premium-old/dist/es/shared/version-check.js';
disableVersionCheck();
// for cjs
import {
disableVersionCheck
} from 'rxdb-premium-old/dist/lib/shared/version-check.js';
disableVersionCheck();
#What is storage migration and how to run schema migrations in PouchDB vs RxDB?
Storage migration involves physically shifting all existing documents from one underlying RxStorage adapter (e.g., IndexedDB) into an entirely different storage engine (e.g., SQLite), often required during platform upgrades. Unlike PouchDB which lacked robust native migration rails, RxDB enforces distinct boundaries between structural Data Migrations (changing schema formats via the migrationStrategy map) and underlying Storage Migrations (migrateStorage()). These two distinct mechanisms must never be executed simultaneously.