IndexedDB 获取对象存储已存在于Onupgradeneeded中

0aydgbwb  于 2022-12-09  发布在  IndexedDB
关注(0)|答案(2)|浏览(193)

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

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 });
    };

这在版本3和4中运行得很好。当运行到版本5时,我得到了错误:
无法在“IDBDatabase”上执行“createObjectStore”:具有指定名称的对象存储已存在。在IDBOpenDBRequest.DBOpenRequest. onupgradeneded
createObjectStore不是在一个新版本的空数据库上运行吗?如何修复此错误?
我碰巧记录了db对象,详细信息如下:

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

suzh9iv8

suzh9iv81#

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时,数据库已经开始升级。但由于在upgradeneeded处理程序中抛出了异常,升级被中止,并且在记录详细信息之前,版本号回滚到4

g52tjvyc

g52tjvyc2#

升级DB的最佳方法是检查存储名称是否已经存在。

openDB('db-name', version, {
  upgrade(db, oldVersion, newVersion, transaction) {
    if(!db.objectStoreNames.contains('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 });
    }
  }
})

使用indexDB API与indexNames和objectStoreNames来检查是否存在某些内容,这使我的代码更加可靠和易于维护,在使用数据库版本控制使用IndexDB中也简要提到了这一点

相关问题