Zope Object Database
The Zope Object Database (ZODB) is an object-oriented database for transparently and persistently storing Python objects. It is included as part of the Zope web application server, but can also be used independently of Zope. Features of the ZODB include: transactions, history/undo, transparently pluggable storage, built-in caching, multiversion concurrency control (MVCC), and scalability across a network (using ). Implementation. Basics. ZODB stores Python objects using an extended version of Python's built-in object persistence (pickle). A ZODB database has a single root object (normally a dictionary), which is the only object directly made accessible  by the database. All other objects stored in the database are reached through the root object. Objects referenced by an object stored in the database are automatically stored in the database as well. ZODB supports concurrent transactions using MVCC and tracks changes to objects on a per-object basis. Only changed objects are committed. Transactions are non-destructive by default and can be reverted. Example. For example, say we have a car described using 3 classes codice_1,codice_2 and codice_3. In Python, this could be represented the following way: class Car: [...] class Wheel: [...] class Screw: [...] myCar = Car() myCar.wheel1 = Wheel () myCar.wheel2 = Wheel() for wheel in (myCar.wheel1, myCar.wheel2): If the variable mycar is the root of persistence, then: zodb['mycar'] = myCar This puts all of the object instances (car, wheel, screws etc.) into storage, which can be retrieved later. If another program gets a connection to the database through the mycar object, performing: car = zodb['myCar'] And retrieves all the objects, the pointer to the car being held in the codice_4 variable. Then at some later stage, this object can be altered with a Python code like: car.wheel3 = Wheel() car.wheel3.screws = [Screw()] The storage is altered to reflect the  change of data (after a commit is ordered). There is no declaration of the data structure in either Python or ZODB, so new fields can be freely added to any existing object. Storage unit. For persistence to take place, the Python Car class must be derived from the persistence. Persistent class — this class both holds the data necessary for the persistence machinery to work, such as the internal object id, state of the object, and so on, but also defines the boundary of the persistence in the following sense: every object whose class derives from Persistent is the atomic  unit of storage (the whole object is copied to the storage when a field is modified). In the example above, if codice_1 is the only class deriving from Persistent, when codice_6 is added to car, all of the objects must be written to the storage. In contrast, if codice_7 also derives from Persistent, then when codice_8 is performed, a new record is written to the storage to hold the new value of the codice_1, but the existing codice_7 are kept, and the new record for the codice_1 points to the already existing codice_7 record inside the storage. The ZODB machinery  doesn't chase modification down through the graph of pointers. In the example above, codice_13 is a modification automatically tracked down by the ZODB machinery, because codice_14 is of (Persistent) class codice_1. The ZODB machinery does this by marking the record as dirty. However, if there is a list, any change inside the list isn't noticed by the ZODB machinery, and the programmer must help by manually adding codice_16, notifying ZODB that the record actually changed. Thus, to a certain extent the programmer must be aware of the working of the persistence machinery. Atomicity. The storage unit (that is , an object whose class derives from Persistent) is also the atomicity unit. In the example above, if codice_17 is the only Persistent class, a thread modifies a Wheel (the codice_1 record must be notified), and another thread modifies another codice_7 inside another transaction, the second commit will fail. If codice_7 is also Persistent, both codice_21 can be modified independently by two different threads in two different transactions. Class persistence. The class persistence—writing the class of a particular object into the storage—is obtained by writing a kind of "fully qualified" name of the class into each record on the  disk. In Python, the name of the class involves the hierarchy of directory the source file of the class resides in. A consequence is that the "source" file of persisting object cannot be moved. If it is, the ZODB machinery is unable to locate the class of an object when retrieving it from the storage, resulting into a broken object. ZEO. Zope Enterprise Objects (ZEO) is a ZODB storage implementation that allows multiple client processes to persist objects to a single ZEO server. This allows transparent scaling.