Search code examples
pythonunqlitenosql

Reading collection from UnQLite?


I'm using nobonobo's python bindings to unqlite and am running into an issue when attempting to work with a JSON document collection.

In the README, there is this JX9 script:

sample = (
    "db_create('users'); /* Create the collection users */"
    "db_store('users',{ 'name' : 'dean' , 'age' : 32 });"
    "db_store('users',{ 'name' : 'chems' , 'age' : 27 });"
    "print db_fetch_all('users')..'\n';"
    "while( ($rec = db_fetch('users')) != NULL ){"
    "  print $rec; print '\n';"
    "}"
)

This correctly prints each record:

[{"name":"dean","age":32,"__id":0},{"name":"chems","age":27,"__id":1}]
{"name":"dean","age":32,"__id":0}
{"name":"chems","age":27,"__id":1}

However when I try to read the collection in Python using a callback, I get garbage back:

@unqlitepy.OutputCallback
def f(output, outlen, udata):
    output = (c_char*outlen).from_address(output).raw
    print locals()
    return unqlitepy.UNQLITE_OK
db.fetch_cb('users', f)

This is the output:

{'udata': None, 'output': 'a\x1e\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x02D\xa7\x83\x0b', 'outlen': 22L}

Similarly if I grab a cursor and print the first user in the users collection, I get this:

'users_0' '\x01\x08\x00\x00\x00\x04name\x05\x08\x00\x00\x00\x04dean\x06\x08\x00\x00\x00\x03age\x05\n\x00\x00\x00\x00\x00\x00\x00 \x06\x08\x00\x00\x00\x04__id\x05\n\x00\x00\x00\x00\x00\x00\x00\x00\x06\x02'

Does anybody know what might be happening? Is there some way to decode the data returned to python?


Solution

  • I wrote some new bindings which make all of this way easier: https://github.com/coleifer/unqlite-python

    >>> users.store([
    ...     {'name': 'Charlie', 'color': 'green'},
    ...     {'name': 'Huey', 'color': 'white'},
    ...     {'name': 'Mickey', 'color': 'black'}])
    True
    >>> users.store({'name': 'Leslie', 'color': 'also green'})
    True
    
    >>> users.fetch(0)  # Fetch the first record.
    {'__id': 0, 'color': 'green', 'name': 'Charlie'}
    
    >>> users.delete(0)  # Delete the first record.
    True
    >>> users.delete(users.last_record_id())  # Delete the last record.
    True
    >>> users.all()
    [{'__id': 1, 'color': 'white', 'name': 'Huey'},
     {'__id': 2, 'color': 'black', 'name': 'Mickey'}]
    
    >>> users.filter(lambda obj: obj['name'].startswith('H'))
    [{'__id': 1, 'color': 'white', 'name': 'Huey'}]