Skip to content Skip to sidebar Skip to footer

Change Collection Class Key Of Reference In Association_proxy

Is it possible to change the key of the collection class of a reference in an association proxy? Example: class Event(ManagerBase): '''Defines an event.''' __tablename__ =

Solution 1:

It seems as this is not possible with the original SQLAlchemy AssociationProxy, as the class accesses the original relationship directly, so any key will be queried 1:1 on the underlying relationship.

I wrote a class DictProxy, which allows changing the key as well as the value fields:

classDictProxy(object):
    def__init__(self, col, keyattr, valattr = None):
        self.obj = None
        self.col = col
        self.keyattr = keyattr
        self.valattr = valattr

    def__get__(self, obj, class_):
        self.obj = obj
        return self

    def__repr__(self):
        outdict = {}
        for k, v ingetattr(self.obj, self.col).iteritems():
            ifnot k isNone:
                if self.valattr == None:
                    outdict[getattr(k, self.keyattr)] = v
                elif v isnotNone:
                    outdict[getattr(k, self.keyattr)] = getattr(v, self.valattr)
                else:
                    outdict[getattr(k, self.keyattr)] = Nonereturnrepr(outdict)

    def__getitem__(self, key):
        keyobj = [obj for obj ingetattr(self.obj, self.col) ifgetattr(obj, self.keyattr) == key]
        ifnotlen(keyobj):
            returnNoneif self.valattr == None:
            returngetattr(self.obj, self.col)[keyobj[0]]
        else:
            returngetattr(getattr(self.obj, self.col)[keyobj[0]], self.valattr)

    def__contains__(self, key):
        returnlen([obj for obj ingetattr(self.obj, self.col) ifgetattr(obj, self.keyattr) == key]) != 0defdict_proxy(*arg):
    return DictProxy(*arg)

Example usage:

classEvent(ManagerBase):
    """Defines an event."""

    __tablename__ = 'eventing_events'id = Column(Integer, primary_key=True)
    device_id = Column(Integer, ForeignKey(EventingDevice.id), nullable=False)
    device = relation(EventingDevice)
    type_id = Column(Integer, ForeignKey(EventType.id), nullable=False)
    type = relation(EventType)
    datetime = Column(DateTime, nullable=False)
    summary = Column(String(500))

    fields = dict_proxy("field_values", "name", "value")

fields of Event now is a dictionary with EventFieldValue.name as a key and accesses the relation field_values (which comes into from EventFieldValue via backref).

Note: Actually this is a readonly proxy, but it might be possible (although tricky) to extend the proxy via a __setitem__ method.

Post a Comment for "Change Collection Class Key Of Reference In Association_proxy"