pythonpython-3.xdatabasezopezodb

ZODB: using both regular FileStorage as well as Zlib compressed storage


I am currently writing a Python desktop app that performs some basic data analysis and data display. The data comes from some experiments in our research lab, and we are storing the data in a ZODB database using a FileStorage.

The code to open the database is fairly straightforward, and looks like what you would expect:

self.storage = ZODB.FileStorage.FileStorage(filename)
self.db = ZODB.DB(self.storage)
self.db_connection = self.db.open()
self.db_root = self.db_connection.root

I would like to start using a compressed storage to try and keep the database file at a smaller size (https://pypi.org/project/zc.zlibstorage/), but I'd like to also maintain backwards compatibility with previous database files that did not use compressed storage.

If I was only using databases with compressed storage, I could simply change the first line of my code, so now my code would read like this:

self.storage = zc.zlibstorage.ZlibStorage(ZODB.FileStorage.FileStorage(filename))
self.db = ZODB.DB(self.storage)
self.db_connection = self.db.open()
self.db_root = self.db_connection.root

But if I did that, how would my program handle regular databases that only use FileStorage and not ZLibStorage? I'd like to handle both.

Is there a way to identify if a FileStorage uses compression or not, and then layer on the ZlibStorage if needed? Something like this:

self.storage = ZODB.FileStorage.FileStorage(filename)
if (self.storage is compressed):                                #pseudocode
    self.storage = zc.zlibstorage.ZlibStorage(self.storage)     #pseudocode
self.db = ZODB.DB(self.storage)
self.db_connection = self.db.open()
self.db_root = self.db_connection.root

Or am I completely misunderstanding how things work? Any help would be appreciated! Thanks!


Solution

  • zstorage = ZODB.FileStorage.FileStorage('testz.fs') # testz.fs has been created with ZlibStorage
    try:
     db = ZODB.DB(zstorage)
    except:
     zstorage.close()
     zstorage = zc.zlibstorage.ZlibStorage(ZODB.FileStorage.FileStorage('testz.fs'))
     db = ZODB.DB(zstorage)
    

    Not as robust as it should be (improve it with the correct Exception which is _pickle.UnpicklingError)