Start · Sprachen · JavaScript · Referenz · IDBObjectStore.keyPath

IDBObjectStore.keyPath

Eigenschaft

Schreibgeschützte Eigenschaft, die den Schlüsselpfad (<code>keyPath</code>) eines Objekt-Speichers zurückgibt – als String, String-Array oder <code>null</code>.

seit JavaScript Baseline: alle modernen Browser (IndexedDB 1.0) Kategorie: webapi

Signatur

IDBObjectStore.keyPath

Beschreibung

Die schreibgeschützte Eigenschaft keyPath eines IDBObjectStore gibt an, aus welcher Eigenschaft der gespeicherten Objekte IndexedDB den Primärschlüssel ausliest. Festgelegt wird der Schlüsselpfad einmalig beim Anlegen des Speichers mit IDBDatabase.createObjectStore(name, { keyPath }). Danach lässt er sich nicht mehr ändern, ohne den Speicher zu löschen und neu anzulegen.

Der Wert kann drei Formen haben:

  • null: Es gibt keinen Inline-Schlüssel. Den Schlüssel übergibt man dann bei add()/put() als zweites Argument, oder ein Schlüsselgenerator (autoIncrement: true) erzeugt ihn.
  • String: Ein Pfad zu einer Eigenschaft, z. B. "id" oder mit Punkt-Notation für verschachtelte Werte, z. B. "meta.uuid".
  • String-Array: Ein zusammengesetzter Schlüssel aus mehreren Eigenschaften, z. B. ["nachname", "vorname"].

Nützlich ist keyPath vor allem für generischen Code wie Export- und Import-Werkzeuge, Migrationen oder Debug-Hilfen. Solcher Code muss wissen, ob Datensätze ihren Schlüssel selbst mitbringen (Inline-Schlüssel) oder ob man ihn separat übergeben muss (Out-of-line-Schlüssel).

Rückgabewert

Typ
string | string[] | null
Beschreibung
Der beim Anlegen festgelegte Schlüsselpfad: ein String, ein Array von Strings (zusammengesetzter Schlüssel) oder null, wenn der Speicher Out-of-line-Schlüssel verwendet.

Beispiele

Schlüsselpfad beim Anlegen festlegen und auslesen

const request = indexedDB.open('shop', 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  const produkte = db.createObjectStore('produkte', { keyPath: 'sku' });
  const logs = db.createObjectStore('logs', { autoIncrement: true });
  const personen = db.createObjectStore('personen', { keyPath: ['nachname', 'vorname'] });

  console.log(produkte.keyPath);
  console.log(logs.keyPath);
  console.log(personen.keyPath);
};
sku null ["nachname", "vorname"]

Generisch speichern – Inline- oder Out-of-line-Schlüssel erkennen

const speichern = (db, storeName, wert, schluessel) =>
  new Promise((resolve, reject) => {
    const tx = db.transaction(storeName, 'readwrite');
    const store = tx.objectStore(storeName);

    // Bei Inline-Schlüssel darf KEIN zweites Argument übergeben werden
    const req = store.keyPath !== null
      ? store.put(wert)
      : store.put(wert, schluessel);

    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });

// Nutzung (db aus indexedDB.open):
// await speichern(db, 'produkte', { sku: 'A-100', name: 'Tasse' });
// await speichern(db, 'einstellungen', 'dunkel', 'theme');

Schlüssel eines Datensatzes aus dem keyPath ermitteln (Export-Hilfe)

const wertAmPfad = (obj, pfad) =>
  pfad.split('.').reduce((o, teil) => o?.[teil], obj);

const schluesselVon = (store, datensatz) => {
  const { keyPath } = store;
  if (keyPath === null) return undefined;
  return Array.isArray(keyPath)
    ? keyPath.map((p) => wertAmPfad(datensatz, p))
    : wertAmPfad(datensatz, keyPath);
};

// Simulierter Store zum Testen
console.log(schluesselVon({ keyPath: 'meta.uuid' }, { meta: { uuid: 'x1' } }));
console.log(schluesselVon({ keyPath: ['nachname', 'vorname'] }, { vorname: 'Anna', nachname: 'Berg' }));
x1 ["Berg", "Anna"]

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung an store.keyPath bleibt ohne Wirkung, im Strict Mode wirft sie einen TypeError. Um den Schlüsselpfad zu ändern, muss man den Speicher in einem onupgradeneeded-Handler löschen und neu anlegen. Die Daten migriert man dabei manuell.
  • Inline-Schlüssel plus Schlüssel-Argument: Hat der Speicher einen keyPath und übergibt man put()/add() trotzdem ein zweites Argument, wirft der Aufruf einen DataError. Umgekehrt führt ein fehlender Schlüssel bei keyPath === null ohne autoIncrement ebenfalls zu einem DataError.
  • Ein Array-Schlüsselpfad lässt sich nicht mit autoIncrement: true kombinieren. Ein leerer String "" als Pfad bedeutet: Der gesamte Wert ist der Schlüssel.
  • Bei Array-Schlüsselpfaden liefert der Getter bei jedem Zugriff eine neue Array-Instanz. Ein Vergleich mit === ist dann also immer false, deshalb besser inhaltlich vergleichen.
  • Die Eigenschaft wird in allen modernen Browsern und in Web Workern unterstützt. Im privaten Modus mancher Browser ist IndexedDB eingeschränkt.