On Jun 2, 7:00 am, Mike Conley <mconl...@gmail.com> wrote: > This looks like an association proxy. Have you tried that? > > http://www.sqlalchemy.org/docs/05/reference/ext/associationproxy.html
I don't see how this is related. From a quick read, it seems that's a simplified way to handle many-to-many relations by hiding the association object and it requires a regular relation to be defined anyway. In my example there are two independent one-to-many relationships and the intermediate table (User) is not just an association object, it's a standalone object. George > On Mon, Jun 1, 2009 at 11:46 PM, George Sakkis <george.sak...@gmail.com>wrote: > > > > > I can't for the life of me figure out how to specify a relation > > spanning 3 tables. I think I've tried all combinations of > > primaryjoin, secondaryjoin, viewonly, foreign_keys, remote_dest and > > all that jazz, to no avail so far. If this is possible at all, there > > should be a sample usage at the docs or at least a recipe on the wiki > > since apparently it's not obvious at all. Below are some of my failed > > attempts; any help will be very much appreciated. > > > George > > > #==================================================== > > > from sqlalchemy.orm import relation, sessionmaker > > from sqlalchemy.ext.declarative import declarative_base > > from sqlalchemy import create_engine, Column, Integer, String, > > ForeignKey, and_ > > > TEST = 5 > > > def main(): > > c = Company() > > u = User() > > a = Address() > > c.employees.append(u) > > u.addresses.append(a) > > session = sessionmaker()() > > session.add(c) > > session.flush() > > print a.company > > > Base = declarative_base(bind=create_engine('sqlite:///:memory:', > > echo=True)) > > > class Company(Base): > > __tablename__ = 'company' > > id = Column(Integer, primary_key=True) > > name = Column(String(50)) > > employees = relation('User') > > > class User(Base): > > __tablename__ = 'users' > > id = Column(Integer, primary_key=True) > > name = Column(String(50)) > > company_id = Column(Integer, ForeignKey(Company.id)) > > addresses = relation('Address') > > > class Address(Base): > > __tablename__ = 'addresses' > > id = Column(Integer, primary_key=True) > > email = Column(String(50)) > > user_id = Column(Integer, ForeignKey(User.id)) > > > # 1st attempt: just a primary join. Fails with > > # sqlalchemy.exc.ArgumentError: Could not locate any equated, > > locally > > # mapped column pairs for primaryjoin condition 'addresses.user_id > > = users.id > > # AND users.company_id = company.id' on relation Address.company. > > For more > > # relaxed rules on join conditions, the relation may be marked as > > viewonly=True. > > if TEST == 1: > > company = relation(Company, > > primaryjoin=and_(user_id==User.id, > > > User.company_id==Company.id)) > > > # 2nd attempt: add viewonly=True. Fails with > > # sqlalchemy.exc.ArgumentError: Could not determine relation > > direction for > > # primaryjoin condition 'addresses.user_id = users.id AND > > users.company_id = > > # company.id', on relation Address.company. Specify the > > 'foreign_keys' > > # argument to indicate which columns on the relation are foreign. > > if TEST == 2: > > company = relation(Company, > > primaryjoin=and_(user_id==User.id, > > > User.company_id==Company.id), > > viewonly=True) > > > # 3rd attempt: add foreign_keys=[user_id]. Fails with > > #sqlalchemy.exc.ArgumentError: Remote column 'users.id' is not > > part of > > # mapping Mapper|Company|company. Specify remote_side argument to > > indicate > > # which column lazy join condition should bind. > > if TEST == 3: > > company = relation(Company, > > primaryjoin=and_(user_id==User.id, > > > User.company_id==Company.id), > > viewonly=True, > > foreign_keys=[user_id]) > > > # 4th attempt: add remote_side=[Company.id]. Fails with > > # sqlalchemy.orm.exc.UnmappedColumnError: No column > > users.company_id is > > # configured on mapper Mapper|Address|addresses... > > if TEST == 4: > > company = relation(Company, > > primaryjoin=and_(user_id==User.id, > > > User.company_id==Company.id), > > viewonly=True, > > foreign_keys=[user_id], > > remote_side=[Company.id]) > > > # 5th attempt: try secondary table/join. Fails with: > > # sqlalchemy.orm.exc.UnmappedColumnError: Column 'users.id' is not > > available, > > # due to conflicting property > > 'id':<sqlalchemy.orm.properties.ColumnProperty > > # object at 0x8f73bac> > > if TEST == 5: > > company = relation(Company, User.__table__, > > primaryjoin=user_id==User.id, > > secondaryjoin=User.company_id==Company.id) > > > # give up :/ > > > if __name__ == '__main__': > > Base.metadata.create_all() > > main() --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---