I created a class CorrelatedProxy inheriting from AssociationProxy that allows the creator function to depend on the owner instance of the association proxy. Essentially it gets a attribute 'correlator' of the something like lambda x: lambda y, z: Constructor(x, y, z), and then intercepts the __get__ of AssociationProxy to create self.creator on the fly by applying the owner instance to the correlator. Now consider the code below.
from sqlalchemy.engine import create_engine from sqlalchemy.ext.declarative.api import declarative_base from sqlalchemy.orm import relationship from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.session import sessionmaker from sqlalchemy.schema import Column, ForeignKey from sqlalchemy.types import Integer from sqlalchemy.ext.associationproxy import AssociationProxy class CorrelatedProxy(AssociationProxy): def __init__(self, *args, **kw): self.correlator = kw.pop('correlator', None) AssociationProxy.__init__(self, *args, **kw) def __get__(self, obj, class_): if obj: self.creator = self.correlator(obj) return AssociationProxy.__get__(self, obj, class_) def correlated_proxy(*args, **kw): return CorrelatedProxy(*args, **kw) Base = declarative_base() class A(Base): __tablename__ = 'table_a' id = Column(Integer, primary_key=True) ab = relationship('AB', backref = 'a', collection_class=attribute_mapped_collection('b')) abnum = correlated_proxy('ab', 'num', correlator=\ lambda a: lambda b, n: AB(a=a, b=b, num=n)) class AB(Base): __tablename__ = 'table_ab' num = Column(Integer) a_id = Column(Integer, ForeignKey('table_a.id'), primary_key=True) b_id = Column(Integer, ForeignKey('table_b.id'), primary_key=True) class B(Base): __tablename__ = 'table_b' id = Column(Integer, primary_key=True) ab = relationship('AB', backref = 'b', collection_class=attribute_mapped_collection('a')) if __name__ == '__main__': engine = create_engine('sqlite:///:memory:') Session = sessionmaker(engine) session = Session() Base.metadata.create_all(engine) aa = A() bb = B() aa.abnum[bb] = 1 assert aa.abnum[bb] == aa.abnum[None] == 1 Basically, no matter, what I do, any time I assign something to the CorrelatedProxy, everything goes normally except that 'None' always becomes a key, assigned to the last value I assigned to the proxy. I tried debugging and tracing, but there's some quantum effect going on where if I inspect some value, some other value changes. I for the life of me can't figure out why it's doing this. I'm guessing it's some Instrumentation effect of SA, but I don't understand the in and outs of that very much. I currently can work around this by filtering out the None, but it'd be nice to know why this occurs and whether it will affect any other elements of my program with whatever is going on underneath. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.