When should I use a PersistentDict, and when should I use a Folder? What is the difference between them in terms of updates, internal structure, performance, etc?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
A
PersistentMapping
is simply a implementation of the pythondict
type (via the standard libraryUserDict
base class) adjusted for the Persistence semantics of the ZODB; it saves from having to set the_p_changed
flag on the nearest class that inherits fromPersistent
every time you alter themapping
.A
Folder
is a much richer type, implementing events, integration with the Zope web interface (ZMI), through-the-web arbitrary properties (attributes with type validation), management of Zope permissions, validation of sub-item ids, import/export, etc. Sub-items folders are stored as attributes on the object itself, with some metadata stored in a private dict on the instance.Use a
Folder
when you need any of those extra services (delegation of permissions, id validation, etc), use aPersistentMapping
otherwise. Performance wise looking up or storing items is not going to differ much; one is a straight pythondict
underneath, the other is the instance__dict__
storing the items.If you are looking for conflict avoidance, you should look into BTrees, the
OOBTree
class is basically a persistent mapping where values are stored in persistent buckets, avoiding collisions in most cases, and providing conflict resolution for the rest.If you want
Folder
semantics withBTree
storage semantics, look at Products.BTreeFolder2, and add-on that implements theFolder
interfaces but stores sub-objects in aOOBTree
instead of as attributes directly on the instances.A PersistentDict (now called a PersistentMapping) is a class that inherits from UserDict.IterableUserDict and persistent.Persistent.
UserDict.IterableUserDict is a built-in python class that simulates an iterable dictionary and persistent.Persistent is a Zope class that enables an instance of itself to be saved in the ZODB.
So a PersistentDict (or PersistentMapping) is basically a dictionary that can be stored as an object in the ZODB.
Normal dictionaries cannot be stored as separate objects in the ZODB. They have to be attributes of some class that inherits from persistent.Persistent.
PersistentDict stores its keys and values inside an actual dictionary (the data attribute).
A PersistentDict cannot be added through the ZMI and I think it's intended mostly for the special case where you want to store a dictionary directly in the zodb.
With a Folder I guess you mean the folder in zope.container.folder. A Folder stores it's children inside an OOBTree object, which is a container that can hold large amounts of objects.
When you want a container that contains instances of other content types, then you should rather go with a Folder.
A Folder has interfaces that a PersistentDict doesn't have and these interfaces may be required for certain adapters or other components to work. For example, the ContainerModified event will only fire when a Folder was modified, not a PersistentDict. There might be all kinds of gotchas like these if you use a PersistentDict as a general purpose Folder.
When it comes to performance, a dictionary will usually be faster until the keyspace becomes very large. Then the scales are tipped towards the OOBTree.