Kyu
Kyu

Reputation: 33

Shelve keeps forgetting the variables it holds

I'm teaching myself how to Python3. I wanted to train my acquired skills and write a command-line backup program. I'm trying to save the default backup and save locations with the Shelve module but it seems that it keeps forgetting the variables I save whenever I close or restart the program.

Here is the main function that works with the shelves:

def WorkShelf(key, mode='get', variable=None):
    """Either stores a variable to the shelf or gets one from it.
    Possible modes are 'store' and 'get'"""
    config = shelve.open('Config')

    if mode.strip() == 'get':
        print(config[key])
        return config[key]

    elif mode.strip() == 'store':
        config[key] = variable
        print(key,'holds',variable)

    else:
        print("mode has not been reconginzed. Possible modes:\n\t- 'get'\n\t-'store'")

    config.close()

So, whenever I call this function to store variables and call the function just after that, it works perfectly. I tried to access the shelf manually and everything is there. This is the code used to store the variables:

WorkShelf('BackUpPath','store', bupath)
WorkShelf('Path2BU', 'store', path)

The problem comes when I try to get my variables from the shelf after restarting the script. This code:

config = shelve.open('Config')
path = config['Path2BU']
bupath = config['BackUpPath']

Gives me this error:

Traceback (most recent call last):
  File "C:\Python35-32\lib\shelve.py", line 111, in __getitem__
    value = self.cache[key]
KeyError: 'Path2BU'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    config['Path2BU']
  File "C:\Python35-32\lib\shelve.py", line 113, in __getitem__
    f = BytesIO(self.dict[key.encode(self.keyencoding)])
  File "C:\Python35-32\lib\dbm\dumb.py", line 141, in __getitem__
    pos, siz = self._index[key]     # may raise KeyError
KeyError: b'Path2BU

Basically, this is an error I could reproduce by calling ShelveObject['ThisKeyDoesNotExist'].

I am really lost right now. When I try to manually create a shelf, close it and access it again it seems to work (even though I got an error doing that before) now. I've read every post concerning this, I thought about shelf corruption (but it's not likely it happens every time), and I've read my script A to Z around 20 times now.

Thanks for any help (and I hope I asked my question the right way this time)!


EDIT


Okay so this is making me crazy. Isolating WorkShelf() does work perfectly, like so:

import shelve

    def WorkShelf(key, mode='get', variable=None):
        """Either stores a variable to the shelf or gets one from it.
        Possible modes are 'store' and 'get'"""
        config = shelve.open('Config')

        if mode.strip() == 'get':
            print(config[key])
            return config[key]

        elif mode.strip() == 'store':
            config[key] = variable
            print(key,'holds',variable)

        else:
            print("mode has not been reconginzed. Possible modes:\n\t- 'get'\n\t-'store'")

        config.close()

    if False:
        print('Enter path  n1: ')
        path1 = input("> ")
        WorkShelf('Path1', 'store', path1)

        print ('Enter path n2: ')
        path2 = input("> ")
        WorkShelf('Path2', 'store', path2)

    else:
        path1, path2 = WorkShelf('Path1'), WorkShelf('Path2')
        print (path1, path2)

No problem, perfect.

But when I use the same function in my script, I get this output. It basically tells me it does write the variables to the shelve files ('This key holds this variable' message). I can even call them with the same code I use when restarting. But when calling them after a program reset it's all like 'What are you talking about m8? I never saved these'.

Welcome to this backup manager.
We will walk you around creating your backup and backup preferences

What directory would you like to backup?
Enter path here: W:\Users\Damien\Documents\Code\Code Pyth
Would you like to se all folders and files at that path? (enter YES|NO)
> n


Okay, let's proceed.
Where would you like to create your backup?
Enter path here: N:\

Something already exists there: 
19 folders and 254 documents

Would you like to change your location?
> n
Would you like to save this destination (N:\) as your default backup location ?    That way you don't have to type it again.
> y
BackUpPath holds N:\

If you're going to be backing the same data up we can save the files location W:\Users\Damien\Documents\Code\Code Pyth    so you don't have to type all the paths again.
Would you like me to remember the backup file's location?
> y
Path2BU holds W:\Users\Damien\Documents\Code\Code Pyth
>>> 
======== RESTART: W:\Users\Damien\Documents\Code\Code Pyth\Backup.py ========
Welcome to this backup manager.
Traceback (most recent call last):
  File "C:\Python35-32\lib\shelve.py", line 111, in __getitem__
    value = self.cache[key]
KeyError: 'Path2BU'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "W:\Users\Damien\Documents\Code\Code Pyth\Backup.py", line 198, in <module>
    path, bupath = WorkShelf('Path2BU'), WorkShelf('BackUpPath')
  File "W:\Users\Damien\Documents\Code\Code Pyth\Backup.py", line 165, in WorkShelf
    print(config[key])
  File "C:\Python35-32\lib\shelve.py", line 113, in __getitem__
    f = BytesIO(self.dict[key.encode(self.keyencoding)])
  File "C:\Python35-32\lib\dbm\dumb.py", line 141, in __getitem__
    pos, siz = self._index[key]     # may raise KeyError
KeyError: b'Path2BU'

Please help, I'm going crazy and might develop a class to store and get variables from text files.

Upvotes: 0

Views: 443

Answers (1)

Kyu
Kyu

Reputation: 33

Okay so I just discovered what went wrong.

I had a os.chdir() in my setup code. Whenever Setup was done and I wanted to open my config files it would look in the current directory but the shelves were in the directory os.chdir() pointed to in the setup.

For some reason I ended up with empty shelves in the directory the actual ones were supposed to be. That cost me a day of debugging.

That's all for today folks!

Upvotes: 1

Related Questions