You're on the right track. :)
Anyway, I needed to solve this one too, so here's what I came up
with. You're right that you need to put the association object in
plain SA.
Note that there is a little Python 2.5 syntax in the __repr__ funcs
in case you're on an older version (nothing essential here requires
2.5).
This might point the way to making this work in Elixir without the
plain SA. Maybe... ??? :)
If you'd like a copy of this whole TG project in a zip file, drop me
a line off-list.
model.py:
----------------------------------------
from sqlalchemy import *
from sqlalchemy.ext.assignmapper import assign_mapper
from turbogears.database import metadata, session
from elixir.statements import Statement
from elixir import Unicode, DateTime, String, Integer, Boolean
from elixir import Date, Time, Entity, has_field, using_options, has_one
from elixir import has_many, belongs_to, has_and_belongs_to_many
class ThingOne(Entity):
has_field('name', Unicode)
using_options(tablename='thing_one')
def __repr__(self):
return "<ThingOne %i %r>" % (self.id if self.id else 0,
self.name)
class ThingTwo(Entity):
has_field('name', Unicode)
using_options(tablename='thing_two')
def __repr__(self):
return "<ThingTwo %i %r>" % (self.id if self.id else 0,
self.name)
# using plain SA for the Association Object:
cat_table = Table('cats_in_hats', metadata,
Column('one_id', Integer, ForeignKey('thing_one.id')),
Column('two_id', Integer, ForeignKey('thing_two.id')),
Column('sorter', Integer),
PrimaryKeyConstraint('one_id', 'two_id')
)
class Cat(object):
def __repr__(self):
return "<CatInHat %i %s -- %s>" % (self.sorter if
self.sorter else 0,
self.one.name,
self.two.name)
cat_mapper = assign_mapper(session.context, Cat, cat_table,
properties=dict(
one=relation(ThingOne, backref='cats'), two=relation(ThingTwo,
backref='cats')))
# Adding the relationships to the Entities
ThingOne.mapper.properties['cats'] = relation(Cat,
order_by=cat_table.c.sorter)
ThingTwo.mapper.properties['cats'] = relation(Cat,
order_by=cat_table.c.sorter)
ThingOne.mapper.properties['twos'] = relation(ThingTwo,
secondary=cat_table,
order_by=cat_table.c.sorter,
primaryjoin=ThingOne.table.c.id==cat_table.c.one_id,
secondaryjoin=cat_table.c.two_id==ThingTwo.table.c.id)
ThingTwo.mapper.properties['ones'] = relation(ThingOne,
secondary=cat_table,
order_by=cat_table.c.sorter,
primaryjoin=ThingTwo.table.c.id==cat_table.c.two_id,
secondaryjoin=cat_table.c.one_id==ThingOne.table.c.id)
---------------------snip------------
and here's some test code that passed the test:
spam = ThingOne(name='spam')
eggs = ThingOne(name='eggs')
foo = ThingTwo(name='foo')
bar = ThingTwo(name='bar')
session.flush()
Cat(one=spam, two=bar, sorter=1)
Cat(one=spam, two=foo, sorter=2)
session.flush()
spam.refresh()
bar.refresh()
assert bar in spam.twos
assert foo in spam.twos
assert spam in bar.ones
assert spam in foo.ones
assert spam.twos[0] is bar
assert spam.twos[1] is foo
HTH. enjoy.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"SQLElixir" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlelixir?hl=en
-~----------~----~----~----~------~----~------~--~---