Hi Michael,

Thanks for your lightning fast reply!

On Thu, 2010-11-18 at 10:17 -0500, Michael Bayer wrote:

> this is correct.  The functionality provided by "secondary" is that SQLA will 
> maintain a table with foreign keys to the related primary keys on either 
> side.  It does not do anything at all with additional columns on the 
> "secondary" table.   If your "secondary" table has additional columns you 
> need to deal with, you no longer use "secondary" and instead use the 
> association object pattern : 
> http://www.sqlalchemy.org/docs/orm/relationships.html#association-object .    
> To make this pattern act more like "secondary" in the usual case, you use 
> associationproxy:  
> http://www.sqlalchemy.org/docs/orm/extensions/associationproxy.html
> 
> You could most likely use the existing orderinglist extension in conjunction 
> with associationproxy to maintain the ordering you want, in Python.

Okay, I updated my example code and it actually works now. However, it
feels like a lot of additional complexity just for adding order.

Greetings, Torsten

-- 
DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
Torsten Landschoff

Office Dresden
Tel: +49-(0)351-4519587
Fax: +49-(0)351-4519561

mailto:torsten.landsch...@dynamore.de
http://www.dynamore.de

Registration court: Mannheim, HRB: 109659, based in Karlsruhe,
Managing director:  Prof. Dr. K. Schweizerhof, Dipl.-Math. U. Franz

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@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.

#! /usr/bin/python

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.orderinglist import ordering_list
from sqlalchemy.ext.associationproxy import association_proxy

meta = MetaData()

collection_table = Table("collection", meta,
    Column("collection_id", Integer, primary_key=True))

item_table = Table("item", meta,
    Column("item_id", Integer, primary_key=True),
    Column("name", String))

collection_item_table = Table("collection_item", meta,
    # Need a surrogate key to allow duplicate entries in the list.
    Column("id", Integer, primary_key=True),
    Column("collection_id", ForeignKey(collection_table.c.collection_id), index=True),
    Column("item_id", ForeignKey(item_table.c.item_id)),
    Column("item_order", Integer))


class Collection(object):
    def shallow_copy(self):
        new = Collection()
        new.items = self.items
        return new

    items = association_proxy("items_relation", "item")

class Item(object):
    def __init__(self, name):
        self.name = name

class CollectionItemAssociation(object):
    def __init__(self, item):
        self.item = item

def maybe_commit(session):
    session.commit()
    pass

mapper(Item, item_table)
mapper(CollectionItemAssociation, collection_item_table, properties=dict(
    item=relation(Item)))
mapper(Collection, collection_table, properties=dict(
    items_relation=relation(
        CollectionItemAssociation,
        order_by=[collection_item_table.c.item_order],
        collection_class=ordering_list('item_order'),)))

engine = create_engine("sqlite:///", echo=True)
Session = sessionmaker(bind=engine)
meta.create_all(engine)

items = [Item(name) for name in ("foo", "bar", "baz", "qux")]

session = Session()
c = Collection()
c.items = items[:3]
session.add(c)
maybe_commit(session)

c.items[1] = items[3]
maybe_commit(session)

assert [x.name for x in c.items] == ["foo", "qux", "baz"]

c.items.append(c.items[0])
maybe_commit(session)
assert [x.name for x in c.items] == ["foo", "qux", "baz", "foo"]

Reply via email to