Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

How to upgrade to Dejavu 1.4

Recalling

Changeset [85] saw a change for sandbox.recall: it used to return an iterator, now it returns a list. Use xrecall now if you want an iterator.

Multirecall is gone now. It used to take arguments in (cls, expr) pairs (until [110]); it's now been folded into recall(classes, expr) (in [120]). The 'classes' arg can be a single Unit class (as before) or a new UnitJoin? class. The 'expr' arg can now handle multiple classes itself. See the "modeling" documentation for complete details.

Triggers

Changeset [71] got rid of UnitProperty?.pre and .post (previously, triggers were implemented by overriding them). Now, you should override UnitProperty.__set__ instead.

Associations

The Unit association architecture changed dramatically in changeset [101], from using factory functions to using non-data descriptors. Therefore:

  1. Most importantly: The helper methods for retrieving related Units may now return either a single Unit (or None) or a list of Units, depending on whether the relation is *-to-one or *-to-many. Example:
    
    >>> class Country(dejavu.Unit):
    ...     pass
    ...
    >>> class City(dejavu.Unit):
    ...     CountryID = dejavu.UnitProperty(int)
    ...
    >>> Country.one_to_many('ID', City, 'CountryID')
    
    ...make some Countries and Cities...
    
    >>> Paris.Country()
    <__main__.Country object at 0x008A6D70>
    >>> France.City()
    [<__main__.City object at 0x008A6D10>, <__main__.City object at 0x008A6C90>]
    >>>
  2. The function dejavu.associate(cls1, key1, cls2, key2) is gone. Instead, call cls1.associate(key1, cls2, key2).
  3. You can now define relationships in one direction only by using the ToOne and ToMany descriptors inside your class definition. Example:
    class Person(Unit):
        MotherID = UnitProperty(int, index=True)
        Mother = ToOne('MotherID', Person, 'ID')
  4. A Unit instance's ._associations attribute is no longer of the form {cls, (key, farKey)}. Now, it is of the form {cls.__name__, UnitAssociation()}. To access the far classes, get each UnitAssociation.farClass.
  5. The unit.first(cls2, **kw) method is gone; it was used mostly for *-to-one relations. If you still need to obtain the first unit from a *-to-many relation, call sandbox.unit(cls2, farID=unit.nearID, **kw) (or recall(cls2, expr)[0] or unit.otherClassName()[0] or xrecall(cls2, expr).next()).

Unit Identifiers

Since [113], Units can now have arbitrary identifiers (not just the "ID" attribute). They are declared in each Unit class' "identifiers" attribute, a tuple of UnitProperty? names which make each instance unique. The base Unit class still has the single "ID" attribute as the only identifier, but you can now override that.

Unit Collections and Engine functions

As a consequence of the "arbitrary identifiers", each unit.identity() is now always a tuple, and UnitCollection?.Members is now a list of such tuples; previously, it was a list of single ID values. Therefore, any UnitCollections? which you have persisted will probably crash when run through a set of Rules--they must be manually migrated to the new format. Hm. I should probably write a tool to help do that.

Anyway, you also need to look at any custom engine functions you might have written, since they also manipulate the .Members attribute. They're probably expecting a list of single ID's and then inserting single ID's back in. Change them to expect and insert tuples from unit.identity().

recur.py and xray.py

These modules are now distributed with Dejavu. You no longer need to hunt for them in some other repository. :)