سؤال

I am doing some PloneFormGen work. Currently PloneFormGen stores entered form entries internally as tuples without associated column information. If new columns (form fields) are added then the existing data becomes invalid.

This could be easily avoided storing data in ordered dictionaries, which retain both entered column order and column ids.

Does ZODB have data type equivalent of ordered dictionary? If possible even with matching API (Python dict-like item manipulation and access)?

هل كانت مفيدة؟

المحلول

you'll probably have to build your own class as I am not aware of any current implementations.

You can find implementations of ZODB persisting ordered dicts based on PersistentDict and OOBtree here:

https://github.com/bluedynamics/node.ext.zodb/blob/master/src/node/ext/zodb/utils.py

This implementations are based on odict package:

http://pypi.python.org/pypi/odict

Since it's not possible to persist dict type inheriting objects to ZODB (because persistent.Persistent and dict has incompatible low level implementations) odict provides a way for easily hooking different base classes (using _dict_impl function internally all over the place). That is the reason why odict package is still used in favour of even python 2.7's ordered dict implementation or other 3rd party ordereddict implementations.

نصائح أخرى

You can use any ordered dict implementation out-of-the-box in the ZODB, but you'll have to mark the parent object (the object that refers to the ordered dict instance) as changed by using either parent = odict_instance every time you change it or by setting _p_changed to True. This will, of course, result in a new persistent record for the parent together with the ordered dict instance.

If you want the ordered dict instance itself to detect changes automatically, you'll probably have to build your own class as I am not aware of any current implementations. That said, it is probably exceedingly easy to do so, especially if you use the ZODB PersistentMapping class as a template on how to build a ordered version of the same. You can't use that class as a mixin, unfortunately, as it refers directly to UserDict methods instead of using super() calls (persistent.Persistent is not a new-style class).

Python 2.7 has a ordered dict class in the standard library. Presumably you are still using Python 2.6 in Plone, so you'd have to backport it. Once you've got it backported however, a PersistentOrderedDict implementation should be a straight copy from the PersistentMapping source code, with all instances of UserDict.IterableUserDict replaced with your OrderedDict port.

Both werkzeug and paste provide ordereddicts. You could no doubt pickle them for your purposes.

If a Python object can be pickled it can be persisted within the ZODB.

Take a look at PersistantMapping, from what I understand it should be sufficient to create a mix-in class like this:

class PersistantOrderedDict(PersistantMapping, OrderedDict):
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top