Persistent to file dictionary using Python module shelve

vegaseat 4 Tallied Votes 867 Views Share

The code shows you how to create a persistent to file dictionary of data using the python module shelve.

Gribouillis commented: useful! +14
''' Shelve_test2.py
use a dictionary object and module shelve
to create a 'persistent to file' dictionary

Python2 creates a single (24kb) file 'phonebook.slv'
Python3 creates 3 much smaller (about 1kb each) files:
  'phonebook.slv.dir'
  'phonebook.slv.dat'
  'phonebook.slv.bak'

Tested with Python27 and Python33  by vegaseat  04sep2013
'''

import shelve

# name shelve byte stream data file
# works with Python2 annd Python3
data_file = 'phonebook.slv'

# open existing shelve file or create new shelve file
sh = shelve.open(data_file)

# a simple dictionary of name:phone pairs
phonebook = {
'Andrew Parson': '880-6336',
'Emily Everett': '678-4346', 
'Peter Power': '765-8344',
'Lewis Lame': '112-2345'
}

# this will save all current phonebook data 
# the access key will be "myphone_dict" (you pick name)
sh["myphone_dict"] = phonebook

# do one more dictionary entry ...
phonebook['Ginger Roger'] = '123-4567'
# you can update and save again before you close
sh["myphone_dict"] = phonebook
# close when done
sh.close()

# testing ...
# open the shelve file again for further work
# remember the access key is "myphone_dict"
sh = shelve.open(data_file)
phonebook2 = sh["myphone_dict"]

# can add another dictionary entry
phonebook2['Larry Lark'] = '923-4568'

# save the current phonebook data to the shelve file 
sh["myphone_dict"] = phonebook2
# close when done
sh.close()

print('-'*30)

# test the contents ...
# retrieve the saved data from the file
sh = shelve.open('phonebook.slv')
phonebook3 = sh["myphone_dict"]

# print the contents
for name, phone in sorted(phonebook3.items()):
    print( "%-20s  %s" % (name, phone) )

print('-'*30)

# close when done
sh.close()

''' result ...
------------------------------
Andrew Parson         880-6336
Emily Everett         678-4346
Ginger Roger          123-4567
Larry Lark            923-4568
Lewis Lame            112-2345
Peter Power           765-8344
------------------------------
'''
Gribouillis 1,391 Programming Explorer Team Colleague

For the sake of comparing tools, here is the same code written with the well known zodb module instead of shelve.

''' zodb_test.py
Use third party module ZODB (zope object database)
to create a 'persistent to file' dictionary

Python 2 and 3 create files
    'phonebook.fs'
    'phonebook.fs.index'
    'phonebook.fs.lock'
    'phonebook.fs.tmp'
The files are not compatible between Python 2 and 3.

Tested with Python27 and Python33 by Gribouillis 2013-Sep-05
'''

# There are a few more necessary imports with zodb
from ZODB.FileStorage import FileStorage
from ZODB.DB import DB
import transaction
from BTrees.OOBTree import OOBTree

# name zodb data file
data_file = 'phonebook.fs'

# open existing zodb storage file or create new file
storage = FileStorage(data_file)
db = DB(storage)
connection = db.open()
sh = connection.root() # <- our starting point, the database root object.

# create a persistent dictionary (technically a b-tree)
phonebook = sh["myphone_dict"] = OOBTree()

# update from an ordinary python dictionary
phonebook.update({
'Andrew Parson': '880-6336',
'Emily Everett': '678-4346', 
'Peter Power': '765-8344',
'Lewis Lame': '112-2345'
})

# do one more dictionary entry ...
phonebook['Ginger Roger'] = '123-4567'

# save to database before you close
transaction.commit()

# close when done. A few more calls than with shelves.
connection.close()
db.close()
storage.close()

# testing ...
# open the zodb file again for further work
# remember the access key is "myphone_dict"
storage = FileStorage(data_file)
db = DB(storage)
connection = db.open()
sh = connection.root()

phonebook2 = sh["myphone_dict"]

# can add another dictionary entry
phonebook2['Larry Lark'] = '923-4568'

# save before you close
transaction.commit()

# close when done
connection.close()
db.close()
storage.close()

print('-'*30)

# test the contents ...
# retrieve the saved data from the file
storage = FileStorage(data_file)
db = DB(storage)
connection = db.open()
sh = connection.root()

phonebook3 = sh["myphone_dict"]

# print the contents
for name, phone in sorted(phonebook3.items()):
    print( "%-20s  %s" % (name, phone) )

print('-'*30)

# close when done
connection.close()
db.close()
storage.close()

''' result ...
------------------------------
Andrew Parson         880-6336
Emily Everett         678-4346
Ginger Roger          123-4567
Larry Lark            923-4568
Lewis Lame            112-2345
Peter Power           765-8344
------------------------------
'''

Next step: comparative benchmarks :). Notice that zodb does not load the whole dictionary when it is accessed, because we chose the OOBTree class. It is suitable for very large data sets.

Gribouillis 1,391 Programming Explorer Team Colleague

For small persistent dictionnaries, there is also a very nice implementation by Raymond Hettinger which let the user choose between json, csv or pickle formats !

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.