3

I'm learning about database files and the dbm module in Python 3.1.3, and am having trouble using some of the methods from the anydbm module in Python 2.

The keys method works fine,

import dbm

db = dbm.open('dbm', 'c')
db['modest'] = 'mouse'
db['dream'] = 'theater'

for key in db.keys():
    print(key)

yields:

b'modest'
b'dream'

but items and values,

for k,v in db.items():
    print(k, v)

for val in db.values():
    print(val)

bring up an AttributeError: '_dbm.dbm' object has no attribute 'items'.

Also, this:

for key in db:
    print(key)

gets a TypeError: '_dbm.dbm' object is not iterable.

Do these methods just not work in the dbm module in Python 3? If that's true, is there anything else that I could use instead?

yndolok
  • 5,197
  • 2
  • 42
  • 46

2 Answers2

2

I think this depends which implementation it chooses to use. On my system, dbm in Python 3 chooses to use ndbm, which is equivalent to the dbm module in Python 2. When I use that module explicitly, I see the same limitations.

It appears anydbm in Python 2 chooses dumbdbm, which is slower, but does support the full dictionary interface.

You might want to look at the shelve module, in both Python 2 and 3, which adds another layer over these interfaces (allowing you to store any pickleable object).

Thomas K
  • 39,200
  • 7
  • 84
  • 86
  • Shelve worked great for iterating through db, but using the items and values methods brought up- UnpicklingError: unpickling stack underflow. Is there any way to access dumbdbm with Python 3? – yndolok Jun 01 '11 at 17:15
1

The purpose of these sort of simple databases is to act as key/value stores. It you want all the values, you have to iterate over all the keys. Ie:

values = [db[key] for key in db.keys()]

That will not be fast. It may me that this sort of key/value store isn't really what you need. Perhaps SQLite would be better?

That said, you can access dumbdbm under the name of dbm.dumb in Python 3.

>>> import dbm
>>> db = dbm.dumb.open('dbm', 'c')
>>> 
>>> db['modest'] = 'mouse'
>>> db['dream'] = 'theater'
>>> for key in db.keys():
...     print(key)
... 
b'modest'
b'dream'
>>> for k,v in db.items():
...     print(k, v)
... 
b'modest' b'mouse'
b'dream' b'theater'
>>> for val in db.values():
...     print(val)
... 
b'mouse'
b'theater'
Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251