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.

Reply via email to