Reputation: 5278
My following code:
shelve_object = shelve.open('data/shelve_data', writeback=True)
print([key for key in shelve_object])
for key in shelve_object:
print(shelve_object[key])
gives me the following output:
['251784238314029058', '259650808973492225', '493076669914152965', '525293044375879690', '272814395237859330']
Traceback (most recent call last):
File "/usr/lib/python3.6/shelve.py", line 111, in __getitem__
value = self.cache[key]
KeyError: '251784238314029058'
I also noticed the following errors in my logs:
File "/usr/lib/python3.6/shelve.py", line 113, in __getitem__
f = BytesIO(self.dict[key.encode(self.keyencoding)])
_dbm.error
File "/usr/lib/python3.6/shelve.py", line 125, in __setitem__
self.dict[key.encode(self.keyencoding)] = f.getvalue()
_dbm.error: cannot add item to database
How is it possible that shelve returns keys that doesn't seem to exist?
Upvotes: 0
Views: 1377
Reputation: 1125368
Either the dbm file backing your shelve is corrupted, or you have some kind of incompatibility between your file and the dbm
backend library used for your shelve file.
shelve
is backed by the dbm
module, and it depends on your OS exactly what specific implementation is used, but generally speaking a dbm
file is an on-disk hash table, a data structure that uses a sparse table structure to efficiently find keys again later on.
To show you all the keys in a file, a dbm
library would scan over the table and give you each key as it finds a non-empty slot. But to find the value for a given key, it would hash the key to come to a number between zero and the maximum size of the table, look at the corresponding row in the table and get you the value.
Between those two techniques there is a discrepancy; you appear to have keys in the wrong location in the table. How that happened is hard to say, it could be that file corruption changed the bookkeeping and the actual table size differs from what the bookkeeping info states it should be. It could be that you changed machines and the hashing implementation is now wrong. Or something else, but we can't really help there, sorry.
Upvotes: 1