On 4/7/07, isaac <[EMAIL PROTECTED]> wrote:

[snipped code all over the place to make it shorter]

> class ThingOne(Entity):
>      has_field('name', Unicode)
>      using_options(tablename='thing_one')
>
> class ThingTwo(Entity):
>      has_field('name', Unicode)
>      using_options(tablename='thing_two')
>
> # 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):
>     pass
>
> 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)

As far as I know, it's slightly better/safer to use the "add_property"
method on the mapper than to add the relation to the properties dict
directly. add_property makes sure that the property is compiled if the
mapper was already compiled.

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

This is not related to Elixir and the way you mix Elixir with
SQLAlchemy (which is fine in itself) but what you do is explicitely
warned against in SQLAlchemy documentation. Here is an excerpt (last
paragraph from 
http://www.sqlalchemy.org/docs/datamapping.html#datamapping_association):

    Note that you should not combine the usage of a secondary relationship with
    an association object pattern against the same association table. This is
    because SQLAlchemy's unit of work will regard rows in the table
tracked by the
    secondary argument as distinct from entities mapped into the table by the
    association mapper, causing unexpected behaviors when rows are changed
    by one mapping and not the other.

Or, at least I think it refers to your use case. Otherwise, I'd
already have implemented what you showed directly in Elixir, because
that would be quite easy to do. In fact, I had actually implemented it
in an earlier "private" version of Elixir but that pattern became
deprecated in SQLAlchemy before the first release of Elixir, so I
didn't port that code to the current code base.

You should rather use the associationproxy plugin. See
http://www.sqlalchemy.org/docs/plugins.html#plugins_associationproxy

I've never tested it with Elixir, but I can't think of any reason it
wouldn't work.

-- 
Gaƫtan de Menten
http://openhex.org

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

Reply via email to