pythondatabaseshelvedbmgdbm

Convert Python shelve from dbm.gnu to dbm.dumb


I am trying to convert data stored in a non-dumb shelve to a dumb shelve, to be able to access my data at a location where the non-dumb libraries are not installed.

My test code for transforming the db data looks like this:

import numpy as np
import shelve
import dbm

# create test shelve
sample = list(range(0, 10))
filename = 'test'
new_filename = 'test-dumb'

with shelve.open(filename) as data:
    data['sample'] = sample
print('current db type: ', dbm.whichdb(filename))


# test test shelve
with shelve.open(filename) as data:
    print('in current db: ', list(data.keys()))


# read test shelve
with shelve.open(filename) as data:
    # store in dumb format
    with dbm.dumb.open(new_filename) as dumb_data:
        dumb_data = data
        print('in new db: ', list(dumb_data.keys()))
print('\nnew db type: ', dbm.whichdb(new_filename))


# check dumb shelve
with dbm.dumb.open(new_filename) as dumb_data:
    print(list(dumb_data.keys()))
    if dumb_data['sample'] == sample:
        print('success: ', sample)
    else:
        print('not yet: ', sample)

The output is the following:

current db type:  dbm.gnu
in current db:  ['sample']
in new db:  ['sample']
new db type:  dbm.dumb
[]
Traceback (most recent call last):
  File "/home/asdf/anaconda3/envs/phievo/lib/python3.7/dbm/dumb.py", line 153, in __getitem__
    pos, siz = self._index[key]     # may raise KeyError
KeyError: b'sample'

What am I doing wrong here?


Solution

  • You need to iterate over the keys of the original database, assigning with:

    dumb_data = data
    

    Will just override dumb_data variable with a "pointer" to data.

    The program should look something like the following:

    import numpy as np
    import shelve
    import dbm
    
    ...
    
    # copy data into dumb
    with shelve.open(filename) as data:
        # store in dumb format
        with dbm.dumb.open(new_filename) as dumb_data:
            for key, value in data.items():
                dumb_data[key] = value
            print('in new db: ', list(dumb_data.keys()))
    

    I just replaced the assignation with:

    for key, value in data.items(): 
        dump_data[key] = value`