keyv icon indicating copy to clipboard operation
keyv copied to clipboard

The `db.iterator` helper function doesn't return an iterable if `useKeyPrefix` is `false`.

Open GabuTheDev opened this issue 6 months ago • 1 comments

Wanted to get rid of the keyv: prefix, seems like the iterator does not provide an iterator anymore (the code inside the for...of does not run anymore on a db without the useKeyPrefix: true property)

While I'm at it, I also wanna report that the db.iterator asks for a parameter which shouldn't be the case. Providing no param should just return an iterable for the whole db.

As a note, normal fetching methods such as db.get(key) work just fine.

import { Keyv } from "keyv";
import KeyvSqlite from "@keyv/sqlite";
// import * as fs from "node:fs";

const db = new Keyv({
	store: new KeyvSqlite("./test.db"),
	useKeyPrefix: false,
});

const data = {};
for await (const [key, value] of db.iterator(undefined)) {
	console.log(`Found key: ${key}`);
	data[key] = value;
}

console.log(data); // this returns {}

// fs.writeFileSync("./new_data.json", JSON.stringify(data, null, 4));

GabuTheDev avatar Jun 03 '25 18:06 GabuTheDev

@GabuTheDev - thanks for sending this over. Right now it looks like you need to add in the prefix / namespace to have this work. Would be happy to support a pull request if you are able too.

jaredwray avatar Jun 10 '25 02:06 jaredwray

@GabuTheDev - We found the issue and it is because at this time you need to also set the namespace to undefined for it to return the data and work correctly. With v6 our migration should be complete and we are hoping that you will only have to set a single variable to make this work correctly.

The migration I am talking about is that currently Keyv's code attempts to do namespace support by adding a Key Prefix such as keyv:key_value. We are migrating this year to having the storage adapters own all namespace support which will be a major breaking change in v6 and due out at the end of year.

import Keyv from "keyv";
import KeyvSqlite from "@keyv/sqlite";

const db = new Keyv({
	store: new KeyvSqlite("./test.db"),
});

// set the namespace since you are no longer using namespaces. 
db.namespace = undefined;
// set useKeyPrefix so Keyv handles it correctly
db.useKeyPrefix = false;

const data = {};
for await (const [key, value] of db.iterator(undefined)) {
	console.log(`Found key: ${key}`);
	data[key] = value;
}

console.log(data); // this returns data now

I will update the documentation on Keyv to explain more also: https://keyv.org/docs/keyv/#api---properties and you can scroll down to useKeyPrefix

jaredwray avatar Jun 21 '25 22:06 jaredwray