我的代码如下(通常是众所周知的对象的命名约定):
worker_threads
对于版本3和版本4运行良好。当它来到版本5时,我收到错误:
无法执行' createObjectStore' on' IDBDatabase':具有指定名称的对象库已存在。 在IDBOpenDBRequest.DBOpenRequest.onupgradeneeded
运行新数据库版本的var DBOpenRequest = window.indexedDB.open("messages", 6);
//...
DBOpenRequest.onupgradeneeded = function(event) {
console.log("Need to upgrade.");
var db = event.target.result;
console.log(db);
db.onerror = function(event) {
console.log("Error upgrading.");
};
// Create an objectStore for this database
var objectStore = db.createObjectStore("messages", { keyPath: "id", autoIncrement: true });
};
是否为空?如何修复错误?
我碰巧记录了createObjectStore
对象,详情如下:
我很好奇为什么版本号在摘要行和展开时有所不同。
答案 0 :(得分:10)
运行在新版数据库上的createObjectStore是否为空?
当你得到upgradeneeded
时,数据库处于你之前留下的任何状态。由于您不知道用户访问过的代码版本,因此您需要查看事件的oldVersion
以了解其中的内容。典型的模式是这样的:
var rq = indexedDB.open('db', 5);
rq.onupgradeneeded = function(e) {
var db = rq.result;
if (e.oldVersion < 1) {
// do initial schema creation
db.createObjectStore('users');
}
if (e.oldVersion < 2) {
// do 1->2 upgrade
var s = db.createObjectStore('better_users');
s.createIndex('some_index', ...);
db.deleteObjectStore('users'); // migrating data would be better
}
if (e.oldVersion < 3) {
// do 2->3 upgrade
rq.transaction.objectStore('better_users').createIndex('index2', ...);
}
if (e.oldVersion < 4) {
// do 3->4 upgrade
db.createObjectStore('messages', ...);
}
if (e.oldVersion < 5) {
// do 4->5 upgrade
// ...
}
}
我很好奇为什么版本号在摘要行和展开时有所不同。
那个很微妙......我相信在5
被记录的时候,数据库已经开始升级了。但在记录详细信息之前,because an exception was thrown in the upgradeneeded
handler the upgrade was aborted和the version number was rolled back到4
。
答案 1 :(得分:3)
升级数据库的最佳方法是检查商店名称是否已经存在。在本例中,我使用 https://npmjs.com/idb
openDB('db-name', version, {
upgrade(db, oldVersion, newVersion, transaction) {
if(!db.objectStoreNames.contain('messages')) {
db.createObjectStore('messages', { keyPath: "id", autoIncrement: true })
}
}
})
如果您需要检查 indexName 是否已经存在,您可以获取 objectStore 并检查 indexNames 属性是否包含您需要的 indexName。
openDB('db-name', version, {
upgrade(db, oldVersion, newVersion, transaction) {
const storeName = transaction.objectStore('storeName')
if(!storeName.indexNames.contains('indexName')) {
storeName.createIndex('indexName', 'propertyName', { unique: false });
}
}
})
使用带有 indexNames 和 objectStoreNames 的 indexDB API 来检查某些东西是否存在使我的代码更加可靠和易于维护,Working with IndexDB Using database versioning 上也简要提到了这一点