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
-~----------~----~----~----~------~----~------~--~---

Reply via email to