I have a many-to-many mapping that joins against a single table. The
relation works fine, except when I try to add a new mapping via the
list created by relation(). To make things extra interesting, I'm
using declarative (which I really like, actually, because it maps in a
fairly straightforward manner to standard SA-isms). Here's the setup:

class Connection(Base):
    __tablename__ = "connections"
    followed_id = Column(Integer, ForeignKey('users.id',
ondelete='cascade'), primary_key=True)
    followed = relation('User', primaryjoin='User.id==Connection.followed_id')

    following_id = Column(Integer, ForeignKey('users.id',
ondelete='cascade'), primary_key=True)
    following = relation('User', primaryjoin='User.id==Connection.following_id')

    followed_viewable = Column(Boolean, default=False)

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    username = Column(String(128), unique=True)
    email = Column(String(128))
    password = Column(String(20))
    settings = Column(PickleType())
    projects = relation('Project', backref='owner')
    quota = Column(Integer, default=10)
    amount_used = Column(Integer, default=0)

    # this is the interesting part
    users_i_follow = association_proxy('i_follow', 'followed')
    i_follow = relation(Connection,
                        primaryjoin=Connection.following_id==id,
                        secondary=Connection.__table__,
                        secondaryjoin=id==Connection.followed_id)

    users_following_me = association_proxy('following_me', 'following')
    following_me = relation(Connection,
                            primaryjoin=Connection.followed_id==id,
                            secondary=Connection.__table__,
                            secondaryjoin=id==Connection.following_id)

    def follow(self, ou):
        self.i_follow.append(Connection(following=self, followed=ou))

So, everything works just fine when I add the connection to the session:
>>> u1 = User("kevin", "foo", "bar")
>>> u2 = User("joe", "foo", "bar")
>>> s.add(u1)
>>> s.add(u2)
>>> s.add(Connection(following=u1, followed=u2))
>>> s.flush()
>>> u1.users_i_follow
[<bespin.model.User object at 0x78ee30>]
>>> u1.i_follow
[<bespin.model.Connection object at 0x7d0c10>]
>>> u2.users_following_me
[<bespin.model.User object at 0x78ed50>]

But when I try to use that follow method defined up there, I get an exception:

  File 
"/Users/admin/projects/bespin/lib/python2.5/site-packages/sqlalchemy/orm/sync.py",
line 81, in _raise_col_to_prop
    raise exc.UnmappedColumnError("Can't execute sync rule for source
column '%s'; mapper '%s' does not map this column.  Try using an
explicit `foreign_keys` collection which does not include destination
column '%s' (or use a viewonly=True relation)." % (source_column,
source_mapper, dest_column))
sqlalchemy.orm.exc.UnmappedColumnError: Can't execute sync rule for
source column 'users.id'; mapper 'Mapper|Connection|connections' does
not map this column.  Try using an explicit `foreign_keys` collection
which does not include destination column 'connections.followed_id'
(or use a viewonly=True relation).

users.id *is* mapped in Connection (twice, in fact, which may be the
problem...)  I'm hoping that there's some simple flag I'm missing
here.

Kevin

-- 
Kevin Dangoor

work: http://labs.mozilla.com/
email: k...@blazingthings.com
blog: http://www.BlueSkyOnMars.com

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