-
-
Notifications
You must be signed in to change notification settings - Fork 650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
change.recreate support (Changing primary key) #88
Comments
Using IndexedDB natively does work, but took me some time to figure out. In case someone else stumbles on this issue, the code below will work. David, please comment if this code displays poor practice or anything that may break in a future Dexie change. (function(){
var database = new Dexie('Testing');
// Original table whose primary key
// will eventually need to change
database
.version(1)
.stores({
things: '&uuid'
});
// Version change whose sole purpose is
// to delete the table. One could create
// a temporary table upon this version
// change to store "things" if that's
// important to you.
database
.version(2)
.upgrade(function(transaction){
transaction.idbtrans.db.deleteObjectStore('things');
});
// Let Dexie take over and recreate the
// table. This would also be a good place
// to populate the table with the "things"
// that you saved, then you can delete the
// temporary table.
database
.version(3)
.stores({
things: '++id'
});
database.open();
database.on('error', function(error){
console.log('Oh no! - ' + error);
});
})(); |
Ok, good that you solved it! My intention has originally been that this should just work by changing the primkey. The issue has been to keep existing data while doing this. Possible to achieve by copying data to another store before deleting it, but there's a bug in IE that makes deleteObjectStore() fail if having read from it. I'll reopen this issue as a reminder to add a unit test for this use case. |
I had the same problem. Thanks to the code above I was able to get it working. However, in my case, I had to add the
|
Moin, I tried and migrated some data using this strategy and came across a strange bug/behaviour. Basically if i set a table let db = new Dexie('TestDB');
db
.version(1)
.stores({
table1: '++id'
});
db
.version(2)
.stores({
table1: null,
table1_tmp: '++id'
})
.upgrade(async t => {
let objects = await t.db.table1.toArray();
// table1_tmp is undefined if it is set to null in the next version?!
await t.db.table1_tmp.bulkPut(objects);
});
db
.version(3)
.stores({
table1: '++id2',
// setting table1_tmp to null here affects the previous upgrade step?!
table1_tmp: null
})
.upgrade(async t => {
// move objects back to table1
}); |
Thanks for pointing out. @chrahunt is working on a rewrite of the update process that will do it step-by-step. I am hoping to get it in to 2.0 release, but can't promise that. |
That'd be great. I'm currently debugging the |
Ok, I gave up the debugging. Here is the workaround involving native IndexedDB access: let db = new Dexie('TestDB');
db
.version(1)
.stores({
table1: '++id'
});
db
.version(2)
.stores({
table1: null,
table1_tmp: '++id'
})
.upgrade(async t => {
let objects = await t.table1.toArray();
let tmpStore = t.idbtrans.objectStore('table1_tmp');
objects.forEach(o => tmpStore.put(o));
});
db
.version(3)
.stores({
table1: '++id2',
table1_tmp: null
})
.upgrade(async t => {
let objects = await new Promise<any[]>((resolve, reject) => {
let request = t.idbtrans.objectStore('table1_tmp').getAll();
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
objects.forEach(o => { o.id2 = o.id; delete o.id; });
await t.table1.bulkPut(objects);
}); |
My bad, I've had two tables that needed an update to the primary key. Making a two step upgrade with nulling the schema, it worked for me as well! |
@sechel Thanks for the workaround, had to put it into a project right now at least. One remark about the workaround: |
@sim642 you are right, I corrected the code. One comment on the use of |
The latest 3.0 release has improved upgrading support for this use case https://github.com/dfahlander/Dexie.js/releases/tag/v3.0.0-alpha.3 (see Improved Database Upgrading (PR #714) under Details. |
My application has the need to change a primary key on a particular table. Can you recommend a concise way of achieving this?
Thanks David!
The text was updated successfully, but these errors were encountered: