phwoar, ok. I think I understand. To break it down:
I have a class Foo which, among other things, contains a dict called vals with keys of dates and values of floats. When I store an instance of Foo, it goes to the foo table, and any items in the vals dict should go into the vals table. For sql alchemy to understand how to store the items from the vals dict, i need an ORM(?) object that describes a single row in the vals table. This manifests as a python object called Val, which for my case has a datetime and float scalar. This maps to the datatypes of the vals table, i.e. one row in the vals table will have a datetime and a float. class Val(object): def __init__(self, key, value): self.date = key self.val = value Then, in the mapping of the Foo object, I create a relation with the Val object called vals_dict, which is a column_mapped_collection with a key of Val.date. This manifests as Foo.vals_dict, which is a dict with datetime keys and Val object as the value. mapper(Foo, foo, properties = dict( vals_dict = relation(Val, secondary=foo_vals, collection_class = column_mapped_collection(vals.c.date)) )) Since a dict with a datetime key giving a Val object is somewhat unwieldy to work with, i create an AssociationProxy called Foo.vals, which when accessed by a given key, returns the 'val' attribute of the given Val object. Foo.vals = association_proxy('vals_dict', 'val') Which seems to do what I want :) Have I understood this correctly, and is this the right way to do it? Thank you for your patience, I am still somewhat new to SQLAlchemy and ORM's in general. #!/usr/bin/env python2.6 from sqlalchemy import * from sqlalchemy.orm import sessionmaker, mapper, relation from sqlalchemy.orm.collections import column_mapped_collection from sqlalchemy.ext.associationproxy import association_proxy from datetime import datetime class Val(object): def __init__(self, key, value): self.date = key self.val = value class Foo(object): def __init__(self, name): self.name = name engine = create_engine('sqlite:///:memory:', echo=True) meta = MetaData(bind=engine) vals = Table('vals', meta, Column('id', Integer, primary_key=True), Column('date', DateTime), Column('val', Float), ) foo = Table('foo', meta, Column('id', Integer, primary_key=True), Column('name', String(50)) ) foo_vals = Table('foo_vals', meta, Column('foo_id', Integer, ForeignKey('foo.id'), primary_key=True), Column('val_id', Integer, ForeignKey('vals.id'), primary_key=True) ) mapper(Val, vals) mapper(Foo, foo, properties = dict( vals_dict = relation(Val, secondary=foo_vals, collection_class = column_mapped_collection(vals.c.date)) )) Foo.vals = association_proxy('vals_dict', 'val') meta.create_all() Session = sessionmaker(bind=engine) session = Session() f = Foo('hello') f.vals[datetime(2009, 9, 28)] = 1.0 f2 = Foo('hello again') f2.vals[datetime(2008, 8, 28)] = 2.0 session.add(f) session.add(f2) session.commit() print "%s -> %s" % (f.name, f.vals) print "%s -> %s" % (f2.name, f2.vals) print f.vals_dict for x in f.vals_dict: print "x = %s" % x y = f.vals_dict[x] print "y = %s" % y print "y.date = %s, y.val = %s" % (y.date, y.val) On Sun, Sep 27, 2009 at 5:59 AM, Michael Bayer <mike...@zzzcomputing.com> wrote: > > > On Sep 26, 2009, at 1:25 PM, BEES INC wrote: > >> class Vals(dict): pass >> >> class Foo(object): >> >> def __init__(self, name): >> self.vals = Vals() >> self.name = name >> >> def add(self, key, value): >> self.vals[key] = value > > you would need to say self.vals[key] = Vals() here. > column_mapped_collection uses full ORM instances as values. In any > case I don't think you mean to map the "vals" table to a "dict" > subclass - the mapping of a table to a class implies how to represent > a single *row*, not the full table as a whole. > > If you are attempting to map from scalar keys to scalar (non object) > values, you should look into using the AssociationProxy to accomplish > that. > > > > >> >> engine = create_engine('sqlite:///:memory:', echo=True) >> meta = MetaData(bind=engine) >> Session = sessionmaker(bind=engine) >> >> vals = Table('vals', meta, >> Column('id', Integer, primary_key=True), >> Column('date', DateTime), >> Column('val', Integer), >> Column('foo_id', Integer, ForeignKey('foo.id')) >> ) >> >> mapper(Vals, vals) >> >> foo = Table('foo', meta, >> Column('id', Integer, primary_key=True), >> Column('name', String(50)) >> ) >> >> mapper(Foo, foo, properties = dict( >> vals = relation(Vals, collection_class = column_mapped_collection >> (vals.c.date)) >> )) >> >> sess = Session() >> meta.create_all() >> >> f = Foo('hello') >> f.add(datetime.now(), 1.0) >> >> >> > > > > > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---