its probably easier to use __missing__ - see attached.
On Mar 13, 2011, at 4:26 AM, Eric Ongerth wrote: > Thank you, Mike. Hmm... I tried exactly that technique, the last time > I found myself with a similar need, a year or two ago. I seem to > remember it only caused the problem to regress one step farther. But > I must have missed something and will probably give it another shot. > > Any suggestions on how to replace the dict in one of these situations > with a defaultdict? Just override __setitem__ and __getitem__ ? > > - Eric > > > On Mar 12, 10:26 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: >> On Mar 10, 2011, at 6:20 PM, Eric Ongerth wrote: >> >>> So, jek, if you're listening, or anyone else -- is there an already >>> existing, working implementation of a Dict of Lists or Dict of Sets >>> collection class? >> >> the association_proxy is always there to flatten the "object" in the middle >> of two relationships typically along an association - so just >> A->relationship->dict of B->relationship->set of C, association proxy from A >> to B.cs. >> >> >> >>> On Mar 10, 1:55 pm, Eric Ongerth <ericonge...@gmail.com> wrote: >>>> Ach, I did it again... proceeded as if column_mapped_collection and >>>> attribute_mapped_collection provide collection classes that are dicts >>>> of lists. No, they're just dicts of scalar values! >> >>>> Again and again I need dicts of lists. They seem to really fit the >>>> data that I tend to work with; A's related to C's indexed by B's (the >>>> B typically indicating the *type* of relationship between the A and >>>> the C). >> >>>> Eventually I need to work my own implementation of dict-of-lists and >>>> dict-of-dicts collection classes up to full strength so I can share >>>> them as a recipe or extension or something. >> >>>> On Mar 10, 1:02 pm, Eric Ongerth <ericonge...@gmail.com> wrote: >> >>>>> I make occasional use of alternate collection classes for my >>>>> sqlalchemy relationships. For example, column_mapped_collection. The >>>>> existing collection classes in sqlalchemy.orm.collections work really >>>>> well for me; I have a lot of relational data that very naturally >>>>> belongs in dicts rather than lists because it makes sense as one thing >>>>> indexed or mapped by another. >> >>>>> I find that I often need to add an item to one of these dict-mapped >>>>> collections and would rather not have to check whether the key already >>>>> exists in the dict. So I'm doing, essentially: >>>>> collection.setdefault(key, []).append(value). >> >>>>> As a matter of syntactic sugar (which alternative collection classes >>>>> already are, anyway) I would like to have collection classes backed by >>>>> dicts with the capability of python's defaultdict, so that I could >>>>> write more simply, and with equivalent results: >>>>> collection[key].append(value) >> >>>>> I understand how to create my own collection class which will behave >>>>> as desired. My question is, has anyone already got code for this that >>>>> I could borrow rather than reinvent the wheel? Thanks in advance. -- >>>>> Eric >> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "sqlalchemy" group. >>> To post to this group, send email to sqlalchemy@googlegroups.com. >>> To unsubscribe from this group, send email to >>> sqlalchemy+unsubscr...@googlegroups.com. >>> For more options, visit this group >>> athttp://groups.google.com/group/sqlalchemy?hl=en. > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To post to this group, send email to sqlalchemy@googlegroups.com. > To unsubscribe from this group, send email to > sqlalchemy+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sqlalchemy?hl=en. >
from sqlalchemy import String, Integer, Column, create_engine, ForeignKey from sqlalchemy.orm import relationship, Session from sqlalchemy.orm.collections import MappedCollection from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.associationproxy import association_proxy import operator class Base(object): id = Column(Integer, primary_key=True) Base = declarative_base(cls=Base) class GenDefaultCollection(MappedCollection): def __missing__(self, key): self[key] = b = B(key) return b class A(Base): __tablename__ = "a" associations = relationship("B", collection_class=lambda: GenDefaultCollection(operator.attrgetter("key")) ) collections = association_proxy("associations", "values") class B(Base): __tablename__ = "b" a_id = Column(Integer, ForeignKey("a.id"), nullable=False) elements = relationship("C", collection_class=set) key = Column(String) values = association_proxy("elements", "value") def __init__(self, key, values=None): self.key = key if values: self.values = values class C(Base): __tablename__ = "c" b_id = Column(Integer, ForeignKey("b.id"), nullable=False) value = Column(Integer) def __init__(self, value): self.value = value engine = create_engine('sqlite://', echo=True) Base.metadata.create_all(engine) session = Session(engine) session.add_all([ A(collections={ "1":set([1, 2, 3]), }) ]) session.commit() a1 = session.query(A).first() print a1.collections["1"] a1.collections["1"].add(4) session.commit() a1.collections["2"].update([7, 8, 9]) session.commit() print a1.collections["2"]
-- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.