Venemo/node-lmdb

Shared database between node and python using node-lmdb

Gfuse opened this issue · 6 comments

Gfuse commented

I am completely new with nodejs and node-lmdb, so I will appreciate if you can help me to understand how to solve my problem.
I am trying to make a shared database between nodejs and python using node-lmdb (0,9,70) in node side and lmdb (0, 9, 22) in python side.

I made a database in node side, then I tried to read data in python side using the following codes, but I could not decode data in python side. Could you help me to read data in a proper format?

The node side output:

Current lmdb version is { versionString: 'LMDB 0.9.70: (December 19, 2015)',
   major: 0,
   minor: 9,
   patch: 70 }
 
 database statistics:
 { pageSize: 4096,
   treeDepth: 1,
   treeBranchPageCount: 0,
   treeLeafPageCount: 1,
   entryCount: 3 }

The out put of the python side:

 (0, 9, 22)
 b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
 [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0]

Best regards

help.zip

Hello,

Unfortunately I don't know Python, never used Python myself. But will try to take a look at your code.

Okay so this is what you have in your JS:

    txn.putNumber(dbi, "key3", 120);
    txn.putNumber(dbi, "majid", 20);
    txn.putNumber(dbi, "maad", 202);

And this in your Python:

raw = txn.get(str(database_name).encode())

In your JS code you put numbers in your database, while on the python side you are reading some raw byte array data, not numbers. I think this is the problem.

Gfuse commented

the point with node-lmdb is that I write the numbers with specific names in an Open database:

var dbi = env.openDbi({
name: "ma",
create: true
});

var txn = env.beginTxn();
txn.putNumber(dbi, "key3", 120);
txn.putNumber(dbi, "majid", 20);
txn.putNumber(dbi, "maad", 202);

While in python side I have access to the database, not specific data

database_name = "ma"

raw = txn.get(str(database_name).encode())

if I write the follwoing code, the output of is: None

raw = txn.get(str("majid").encode())

Okay so here is the documentation for the Python lmdb module: https://lmdb.readthedocs.io/en/release/ ― it tells you how to access each item in your database as a binary. In node-lmdb you can also work with binaries, so that seems to be the easiest way to co-operate between the two.

Gfuse commented

Dear Venemo, thank you for your suggestion. I solved it by using your suggestion. In following you will find the codes.

JS side:

var lmdb = require('node-lmdb');

function createBinary(dec){
    var b = null;
    if (isNaN(dec)) {
      b = new Buffer(dec);
    } else {
      b = new Buffer(dec.toString());
    }
    return b
}
console.log("Current lmdb version is", lmdb.version);
var env = new lmdb.Env();
env.open({
    path: "./database",
    maxDbs: 10
});
// Open database
var dbi = env.openDbi({
   name: "ma",
   create: true
});

// Begin transaction
var txn = env.beginTxn();

var stat = dbi.stat(txn);
console.log("\ndatabase statistics:");
console.dir(stat);
    txn.putBinary(dbi, createBinary("key3"),createBinary(200));
    txn.putBinary(dbi, createBinary("mad"), createBinary(300));
    txn.putBinary(dbi, createBinary("maad"), createBinary(100));
console.log(txn.getBinary(dbi, createBinary("key3")) ? txn.getBinary(dbi, createBinary("key3")).toString() : null);
console.log(txn.getBinary(dbi, createBinary("mad")) ? txn.getBinary(dbi, createBinary("mad")).toString() : null);
console.log(txn.getBinary(dbi, createBinary("mum")) ? txn.getBinary(dbi, createBinary("mum")).toString() : null);
console.log("Run this example again to see the alterations on the database!");

// Commit transaction
txn.commit();

// Close the database
dbi.close();
// Close the environment
env.close();

The python side:

import lmdb
import os

def lmdb_read(database_name, path_lmdb):
    if(os.path.isdir(path_lmdb)):
        _lmdb_env = lmdb.open(path_lmdb, subdir=True, max_dbs=10)
        print(_lmdb_env.stat())
        db0 = _lmdb_env.open_db(str(database_name).encode())
        with _lmdb_env.begin(write=True, db= db0) as txn:
            print(txn.get(b'maad'))
            print(txn.get(b'mad'))
            print(txn.get(b'key3'))
            txn.put(b'mum', b'012345678', db=db0)
    else:
        print("Database dose not exist!!")
    return 0

print(lmdb.version())
data = lmdb_read("ma",'./database')

@majid1268 I'm really happy you could solve your problem. I'm closing this issue now. If you encounter any more problems please open a different issue.