我在没有任何其他修改的情况下升级版本时遇到此代码的问题,我无法理解原因。
function create_registry() {
var version = 1;
var indexeddb_db = "examples"; // database
var indexeddb_table = "examples_table"; // table
// open the database
var indexeddb_request = indexedDB.open( indexeddb_db, version ); // connect + open database
var db = false;
// if error
indexeddb_request.onerror = function ( event ) {
console.log( event.target );
console.trace();
}
// if success
indexeddb_request.onsuccess = function ( event ) {
console.log( event.target );
console.trace();
}
// if onupgradeneeded
indexeddb_request.onupgradeneeded = function( event ) {
console.log( event.target );
console.trace();
db = event.target.result;
var objectStore = db.createObjectStore( indexeddb_table, { keyPath: 'url' } );
}
}
第一次加载页面时,会创建indexedDB对象(数据库)并创建内部表。一切正常。首先执行onupgradeneeded,然后启动onsuccess。
如果我重新加载页面而没有任何更改,一切正常,onsuccess就会启动。
但是,如果我更改了版本号,那么我会得到下面提到的错误。这些错误在W3C spec of the Indexed Database API中简要描述,但到目前为止对我没什么帮助。执行onupgradeneeded后,执行onerror并且我有一个AbortError,但这并没有告诉我更多。
Chrome 28 “未捕获错误:ConstraintError:DOM IDBDatabase异常0”
Firefox 22 “事务中的变异操作失败,因为不满足约束。例如,对象存储或索引等对象已经存在,并且请求尝试创建新对象。”
据我所知,问题是我正在尝试使用相同的密钥路径重新创建相同的对象,但不是新版本使脚本重新创建整个对象?
为什么我收到错误? 是不是onupgradeneeded只更新版本号并重写对象(数据库)?
答案 0 :(得分:5)
据我所知,问题是我正在尝试使用相同的密钥路径重新创建相同的对象
这是正确的。虽然keypath与它无关,但只是对象存储与现有对象存储具有相同的名称。
不是使脚本重新创建整个对象的新版本吗?
没有。除非您在onupgradeneeded
中手动删除对象存储(以及索引和数据),否则它们将在升级期间保持不变。因此,为了避免该错误,您应该检查event.oldVersion
,它将在第一次创建数据库时为0,随后将是以前的版本号。 然后,您可以仅在首次初始化数据库时创建对象存储,或者在升级时重新创建数据库时将其删除。
更新:MDN IDBDatabase.createObjectStore上的相关文档,阐明了如何使用此调用需要唯一性。
IDBDatabase接口的createObjectStore()方法创建并返回 new 对象存储或索引。
该方法采用商店名称以及允许您定义重要可选属性的参数对象。您可以使用该属性唯一标识商店中的各个对象。由于属性是标识符,对于每个对象都应该是唯一的,并且每个对象都应该具有该属性。