Python is an object-oriented language. Relational databases notoriously aren't. So how do the twain meet? Ideally, you'd want to write code that goes like this:
class Person def __init__(self, name, age): name = name age = age
person = Person("Boudewijn Rempt", 33)
instead of this:
myStatement = """insert into person (name, age) values (%s, %i)"""
dbCursor.execute(myStatement % ("Boudewijn Rempt", 32))
There are two possible approaches to achieving an object-oriented view of your data: wrapping the underlying relational database in an object-oriented middleware component, or directly using an object-based database.
Matisse is one object database that offers Python bindings and that also offers SQL support.
ZODB is really easy to use. Basically, once you've created the database, you have a root dictionary that you can add your Python objects to. You can add, delete, and update objects to your heart's content, if only you remember that your objects must be pickleable. That means that you cannot store code objects (methods, classes, function) or file objects (files, sockets).
On the other hand, because you are basically working with Python dictionaries, you are limited to the kind of manipulations dictionaries support. That means that retrieving all the objects where, say, the Name field contains "Rempt" is harder than with a relational database, where you can write a simple query. With ZODB, you have to iterate over the contents of your dictionary and check every item.
On top of ZODB sits ZEO, the Zope Enterprise Objects. This makes ZODB a standalone database server that can be accessed from many clients over the network. The distribution of ZODB comes with an extensive programming guide.