IndexedDB:ConstraintError:无法将键添加到索引“[index_name]”:至少有一个键不满足唯一性要求

问题描述 投票:0回答:1

我在尝试使用事务中的 put() 方法更新现有记录的“标题”字段时收到此错误。我有一个名为“hotkey”的字段,它有一个具有 unique: true 约束的索引。

以下是相关代码:

request3.onupgradeneeded = (event) => {
            console.log('INSIDE onupgradeneeded for hotkeys', event);
            handles["db3"] = event.target.result;
            // Create an objectStore to hold information about our hotkeys. 
            const hotkeyStore = handles["db3"].createObjectStore(dbName3, {autoIncrement: true});
            // Create an index to search hotkeys by letter. No duplicates
            hotkeyStore.createIndex("hotkey", "hotkey", { unique: true });
            hotkeyStore.createIndex("sort", "sort", { unique: false });
        };
    async function updateRecord(dbName, payload) {
        return new Promise(async (resolve, reject) => {

            setTable(dbName);            
            // open a read/write db transaction, ready for adding the data
            const transaction = handles[activeDB].transaction([dbName], "readwrite");
            // create an object store on the transaction
            const objectStore = transaction.objectStore(dbName);
            console.log(objectStore.keyPath);
            const keyToUse = objectStore.keyPath !== null ? objectStore.keyPath : 'key';
            console.log(payload);           
            for(let record of payload) {
                console.log("WORKING ON: ", record);
                if (!record.hasOwnProperty(keyToUse)) {
                    console.log('keypath for record not present in record, canceling update', record);
                    resolve(false);
                }
                var id = record[keyToUse];
                if (keyToUse == 'key') id = parseInt(id);
                console.log('Searching for record with keyPath ', id);
                const getRequest = objectStore.get(id);

                getRequest.onsuccess = function () {
                   var obj = getRequest.result;
                   if(!obj) {
                     console.log('no matching object for id, canceling update', id);
                     resolve(false);
                     return;
                   }              
                   console.log('loaded object to modify', obj);              
                   // make some changes to the properties of the object loaded 
                   // in memory
                   Object.keys(record).forEach(key => {
                    if (key !== keyToUse && record[key] !== obj[key]) {
                        console.log('UPDATE TO ' + key);
                        const value = record[key];                        
                        obj[key] = value;    
                    }
                   });                   
                   
                   // now store the new object in place of the old object
                   console.log('storing new object in place of old', obj);
                   objectStore.put(obj);
                };                
            }
            transaction.done;

            transaction.oncomplete = function () {
                console.log("ALL PUT TRANSACTIONS COMPLETE.");
                resolve(true);
            }

            transaction.onerror = function (event) {
                console.log("PROBLEM UPDATING RECORDS.", event.target.error);
                resolve(false);
            }
        });
    }

这是控制台日志输出:

null
DBManager.js:164 [{…}]0: {title: 'Not Qualified', description: 'Description', hotkey: 'x', sort: '1', key: '2'}length: 1[[Prototype]]: Array(0)
DBManager.js:166 WORKING ON:  {title: 'Not Qualified', description: 'Description', hotkey: 'x', sort: '1', key: '2'}
DBManager.js:173 Searching for record with keyPath  2
DBManager.js:183 loaded object to modify {title: 'N/A', description: 'Description', hotkey: 'x', sort: '1'}
DBManager.js:188 UPDATE TO title
DBManager.js:195 storing new object in place of old {title: 'Not Qualified', description: 'Description', hotkey: 'x', sort: '1'}
DBManager.js:207 PROBLEM UPDATING RECORDS. ConstraintError: Unable to add key to index 'hotkey': at least one key does not satisfy the uniqueness requirements.
configuration.js:252 false
DBManager.js:314 FAILED TO OPEN DB.

有人可以协助以正确的方式更新 IndexedDB 中具有唯一索引的记录吗?

javascript indexeddb
1个回答
0
投票

由于您的热键是唯一的约束,请确保数据库中不存在您尝试为热键设置的值。您可以先使用 select First 进行检查,如果该热键值已经存在,则可以返回任何错误。

async function updateRecord(dbName, payload) {
return new Promise(async (resolve, reject) => {
    setTable(dbName);            
    const transaction = handles[activeDB].transaction([dbName], "readwrite");
    const objectStore = transaction.objectStore(dbName);
    const keyToUse = objectStore.keyPath !== null ? objectStore.keyPath : 'key';

    for (let record of payload) {
        if (!record.hasOwnProperty(keyToUse)) {
            console.log('keypath for record not present in record, canceling update', record);
            resolve(false);
        }

        const id = keyToUse === 'key' ? parseInt(record[keyToUse]) : record[keyToUse];
        const getRequest = objectStore.get(id);

        getRequest.onsuccess = async function () {
            const existingRecord = getRequest.result;
            if (!existingRecord) {
                console.log('no matching object for id, canceling update', id);
                resolve(false);
                return;
            }

            if (record.hotkey && record.hotkey !== existingRecord.hotkey) {
                const hotkeyIndex = objectStore.index("hotkey");
                const hotkeyRequest = hotkeyIndex.get(record.hotkey);

                hotkeyRequest.onsuccess = function () {
                    const conflictingRecord = hotkeyRequest.result;
                    if (conflictingRecord && conflictingRecord[keyToUse] !== id) {
                        console.log("Conflict detected in 'hotkey' field. Aborting update.");
                        resolve(false);
                        return;
                    }

                    updateObjectStore(objectStore, existingRecord, record);
                };

                hotkeyRequest.onerror = function (event) {
                    console.log("Error checking for hotkey conflict:", event.target.error);
                    resolve(false);
                };
            } else {
                updateObjectStore(objectStore, existingRecord, record);
            }
        };
    }

    transaction.oncomplete = function () {
        console.log("ALL PUT TRANSACTIONS COMPLETE.");
        resolve(true);
    };

    transaction.onerror = function (event) {
        console.log("PROBLEM UPDATING RECORDS.", event.target.error);
        resolve(false);
    };
});

}

您始终可以创建辅助函数,但这是可选的

function updateObjectStore(objectStore, existingRecord, newRecord) {
Object.keys(newRecord).forEach(key => {
    if (newRecord[key] !== existingRecord[key]) {
        existingRecord[key] = newRecord[key];
    }
});

objectStore.put(existingRecord);

}

© www.soinside.com 2019 - 2024. All rights reserved.