New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't get persistence working in node. #563
Comments
Hello @benoneal, just now I start using LokiJS and had the same issues than you: no persistence. I did what you mentioned here in your post (adding So I would guess, that you have a permission issue on your computer which prevents LokiJS from doing what you expect it to to. Maybe you should check this and try a temp directory path where everything is allowed, just to be sure. Here is my extremely simple starter implementation of LokiJS which persists and autoloads. Maybe it can help you in any way:
Regards, |
@techfort The docs should be fine-tuned in the section about persistence as I think this issues here hits many people trying out LokiJS and maybe let them put it aside because it's not working like described which gives a bad "first impression" ;) |
@Mika83AC in your example above you don't use persistence adapter at all. So your collection won't be saved to disk. I had the same problem as @benoneal I could not make lokijs works with loki-fs-structured-adapter to save collection to the disk. The solution was not to use In case anyone need working code, this is how to make const loki = require('lokijs');
const path = require('path');
const LokiFSStructuredAdapter = require('lokijs/src/loki-fs-structured-adapter');
let dbFile = path.resolve(__dirname, './test-data.json');
let Db = new loki(dbFile,
{
verbose: true,
autosave: true,
// autoload: true,
autosaveInterval: 1000,
adapter: new LokiFSStructuredAdapter(),
// autoloadCallback: databaseInitialize,
autosaveCallback: () => {
console.log('autosaved db');
}
}
);
function databaseInitialize(cb) {
let entries = Db.getCollection('test');
if (entries === null) {
console.log('test collection is empty, ADDING new collection test');
entries = Db.addCollection('test', { unique: ['id'] });
entries.insert({id: 1, test: 'test'});
entries.insert({id: 2, test: 'test2'});
entries.insert({id: 3, test: 'test3'});
}
cb();
}
const loadDb = (cb) => {
databaseInitialize(callback => {
Db.loadDatabase({}, function (err) {
if (err) console.error('db load errors', err);
cb({
Db: Db,
test: Db.getCollection('test')
});
});
});
};
// module.export = loadDb;
// then use loadDb in other file like index.js
loadDb(({Db, test})=> {
console.log('db loaded', Db);
console.log('entries in db collection test', test.find());
}); |
We now have some quickstart examples in the examples folder which cover basic persistence setup. Web users can find equivalent web quickstart scripts in LokiSandbox now. These (node) examples from the examples folder should be a good start : |
@obeliskos |
I built a library around LokiJs that might address this issue. https://www.npmjs.com/package/lokijs-promise Decided to build this as quite a lot of the issues that I found in the Issues section revolved around loading the persistent store (eg. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
A note that could help future visitors here: I was trying to write a script that runs and then exits on completion, after saving changes to the database. If I set this up as
the changes wouldn't save, but they do save correctly if I instead write |
How do I get it enabled ? I like to autosave to json. Please help :-) |
I
You have to wait for the database to load. use the callback |
I'm trying to set up loki in node. I've followed through the various documentation around this. The docs are sometimes inconsistent with regards to things like adapters, and some things are never explained.
For example, when constructing loki, the docs always pass in a string, like
const db = new loki('loki.json')
or something. Apparently this is "where data is persisted"? So some observations I've run into while trying to get this working:const db = new loki('../data/db.json')
> Error: no such file or directoryc:/data/db.json
const db = new loki(path.resolve(__dirname, '../../data/db.json'))
> Error: no such file or directoryc:/code/app/data/db.json
So it needs to be an absolute path. The docs never mention this, and indeed all examples appear to be a relative path. Also the file needs to exist. The docs never mention this.
When I create a file in that location, even an empty file, loki will "work". I can add collections, insert items, and find and return them. Here's an example from my testing:
However, nothing is persisted to
db.json
. No matter how long I leave the process running,db.json
remains completely empty. Reading further into the docs, I find reference to some options that need to be supplied.const db = new loki(fileStorage, {autosave: true, autosaveInterval: 5000})
I have no idea why loki would throw an error if you don't supply a valid path to an existing file, if it's not going to use it anyway without explicit options... that seems weird. What's weirder, is that even supplying these options doesn't appear to do anything. No matter how long the process is left running, nor how many things items I insert into a collection,
db.json
is never changed. Nothing is being persisted.So I try something else. What if
db.json
was pre-seeded with some data? After all, in production, this will be the norm after the first boot. But nowhere in the docs does it mention anything about the structure of the saved file. I had to copy an example from the LEAN ejs stack.Now I have a manually seeded
db.json
:So modifying my original code, I should, in theory, be able to read directly from the pre-existing data:
Wat.
After more digging, I find another option
autoload
, that must surely be the thing I need?const db = new loki(fileStorage, {autosave: true, autosaveInterval: 5000, autoload: true})
Alas, it is not. Even with this option, it still throws
TypeError: Cannot read property 'find' of null
.About now I'm starting to abandon hope of ever using Lokijs. It demands a valid path to an existing file, then completely ignores the file contents and never changes it. It will happily create and read from data in memory, but then all is lost when the process ends.
The docs mention something about adapters. They do state that Lokijs will detect when it is running in node, and use its
LokiFsAdapter
by default. Maybe that's the problem? They talk about using the alternateLokiFsStructuredAdapter
as a way to manage larger data stores (which I anticipate I'll need), so I try switching over to that adapter in a last-ditch effort to get this working:Oh look a new error. Worth mentioning, this documentation on persistence adapters says to pass the adapter in directly (
var db = new loki('sandbox.db', { adapter : lfsa})
), which gives a whole different error (TypeError: this.persistenceAdapter.loadDatabase is not a function
) which is why I passed it in as an instance above.This seems like a pretty monumental problem. Surely it's big enough that other people would be running into it. But there are no other issues even remotely relating to this problem! I have literally no idea what is the problem, and I feel like I've exhausted my options to solve this myself.
Environment:
I would love to use Lokijs, because it's the cleanest and most direct API to my data. Obviously, without being able to load existing data, or persist new data, it's a non-starter for me. I'd really appreciate any help or insight into this problem, so I can avoid falling back on postgresql or some other convoluted impedence mismatch nightmare.
The text was updated successfully, but these errors were encountered: