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"