获取对象存储已经存在于onupgradeneeded中

时间:2017-05-16 13:10:42

标签: javascript indexeddb

我的代码如下(通常是众所周知的对象的命名约定):

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对象,详情如下:

enter image description here

我很好奇为什么版本号在摘要行和展开时有所不同。

2 个答案:

答案 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 abortedthe version number was rolled back4

答案 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 上也简要提到了这一点