fear_matrix
fear_matrix

Reputation: 4960

Want to update/modify the value of key in shelve

I have a data (i.e {'/domflight': 10, '/intlflight': 20}) and want to modify the value of '/domflight' to 50. Below is my code which I am trying to do but no luck.

import shelve
s = shelve.open('/tmp/test_shelf.db')
try:
        print s['key1']
        s['key1']['/domflight'] = 50
finally:
        s.close()

s = shelve.open('/tmp/test_shelf.db', writeback=True)
try:
        print s['key1']
finally:
        s.close()

Upvotes: 0

Views: 1910

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122172

Shelve cannot detect changes to nested mutable objects. Setting a key in a nested dictionary does not trigger a save.

Re-set the dictionary instead:

nested_dict = s['key1']
nested_dict['/domflight'] = 50
s['key1'] = nested_dict

It is the assignment back to s['key1'] that triggers a save.

Technically, what happens is that s is a subclass of the UserDict.DictMixin class with a custom __setitem__ method. Assigning directly to keys in the s object calls that method an the change is saved. But assigning to a mutable object that is nested under a key will not trigger a call to __setitem__, thus the change is not detected and nothing is saved.

This is covered in the documentation:

Because of Python semantics, a shelf cannot know when a mutable persistent-dictionary entry is modified. By default modified objects are written only when assigned to the shelf (see Example). If the optional writeback parameter is set to True, all entries accessed are also cached in memory, and written back on sync() and close(); this can make it handier to mutate mutable entries in the persistent dictionary, but, if many entries are accessed, it can consume vast amounts of memory for the cache, and it can make the close operation very slow since all accessed entries are written back (there is no way to determine which accessed entries are mutable, nor which ones were actually mutated).

Upvotes: 3

Related Questions