pythondictionarynestedshelvesetdefault

setdefault() in nested dictionary?


trying to store the values in a nested dictionary in a shelve file with setdefult(). Is there any easy way to do this? The following code seems to make the values immutable, for example, the last line is unable to change the 'price' value to 25.

room_data = shelve.open("data")

room_data.setdefault("key", {"type": "Standard Single", "available": 5, "price": 50, "adults": 1, "children": 0})

room_data["key"]["price"] = 25

I was hoping to get it functioning with shelve then add SQL later but it might be easier to just learn that now. Let me know what you think. Thanks.


Solution

  • You have to set writeback=True:

    room_data = shelve.open("data", writeback=True)
    

    And then call room_data.sync() after mutating a value:

    room_data.setdefault("key", {"type": "Standard Single", "available": 5, "price": 50, "adults": 1, "children": 0})
    
    room_data["key"]["price"] = 25
    
    room_data.sync()
    

    Otherwise the value is set but the set value can't be mutated.

    From note on shelve.open:

    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).