Dexie.js icon indicating copy to clipboard operation
Dexie.js copied to clipboard

Version Upgrade Not Running On Install

Open salesvue-alex opened this issue 7 years ago • 2 comments

I have a table in the existing version of my db that I would like to add default rows to in a new version.

import Dexie from 'dexie';

const db = new Dexie('MyDB');

//Initially I only had one table
db.version(1).stores({
  TableA: '++id,&name'
});

//In version two I added another table
db.version(2).stores({
  TableB: '++id,&name'
});

//In version three I decided that I wanted some default data in TableB
db.version(3).upgrade(transaction => {

  console.log('creating defaults');

  return transaction.TableB.bulkAdd([
    {name: 'Default 1'},
    {name: 'Default 2'}
  ]);

});

export default db;

This works as expected when upgrading from version 2 to version 3, but on initial database creation the version 3 upgrade is never run.

salesvue-alex avatar Sep 08 '18 19:09 salesvue-alex

Upgraders only run when there's an existing version installed. Use db.on('populate') to define how to populate a DB initially. Upgraders are only for delta changes in data.

dfahlander avatar Sep 10 '18 07:09 dfahlander

This is an old issue so I hope this is an appropriate place to respond. It seems this is still relevant unless something has changed, but as of 3.2.2 the behaviour is the same.

I think it would be good to reassess this. Consider the following use case:

const db = new Dexie('foo');
// Bunch of previous versions
db.version(25).stores({
  fooOptions: 'key'
}).upgrade(tx => tx.fooOptions.bulkAdd([
  { key: 'a', description: 'Desc A' },
  { key: 'b', description: 'Desc B' },
  { key: 'c', description: 'Desc C' }
]));

db.version(26).stores({
    barOptions: 'key'
}).upgrade(tx => tx.fooOptions.add(
  { key: 'd', description: 'Desc D' }
).then(() => tx.fooOptions.delete('a')));

Lets assume I already have a lot of existing migrations.

  • In version 25, I add a new feature where the user can pick from some options. I want to pre populate the table with some defaults.
  • In version 26, I add barOptions which makes option a in fooOptions redundant, but also introduces a new option d.

Using the current approach, I would need to maintain the data twice, because I would also need a separate area to handle the populate event. As such, the whole lot would need to look like so:

const db = new Dexie('foo');
// Bunch of previous versions
db.version(25).stores({
  fooOptions: 'key'
}).upgrade(tx => tx.fooOptions.bulkAdd([
  { key: 'a', description: 'Desc A' },
  { key: 'b', description: 'Desc B' },
  { key: 'c', description: 'Desc C' }
]));

db.version(26).stores({
    barOptions: 'key'
}).upgrade(tx => tx.fooOptions.add(
  { key: 'd', description: 'Desc D' }
).then(() => tx.fooOptions.delete('a')));

// Run this on new creation as well
db.on('populate', tx => {
  tx.fooOptions.bulkAdd([
    { key: 'b', description: 'Desc B' },
    { key: 'c', description: 'Desc C' },
    { key: 'd', description: 'Desc D' },
  ]);
});

It would make it a lot easier to isolate discrete changes by having the upgrade function run as part of the database creation.

Appreciate any thoughts on this.

evantrimboli avatar May 16 '22 06:05 evantrimboli