Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Several many to many table joins with sqlalchemy

New with SQLalchemy, here is my problem:

My model is:

user_group_association_table = Table('user_group_association', Base.metadata,
    Column('user_id', Integer, ForeignKey('user.id')), 
    Column('group_id', Integer, ForeignKey('group.id'))    
)

department_group_association_table = Table('department_group_association', Base.metadata,
    Column('department', Integer, ForeignKey('department.id')), 
    Column('group_id', Integer, ForeignKey('group.id'))
)

class Department(Base):
    __tablename__ = 'department'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))


class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    users = relationship("User", secondary=user_group_association_table, backref="groups")
    departments = relationship("Department", secondary=department_group_association_table, backref="groups")

class User(Base):

    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    firstname = Column(String(50))
    surname = Column(String(50))

So, this code reflects the following relationships:

   --------             ---------             --------------
   | User | --- N:M --- | Group | --- N:M --- | Department |
   --------             ---------             --------------

I tried to work with joins but still not succeeded in doing the following :

One sqlalchemy request to get all the users instances while knowing a departement name (let's say 'R&D")

This should start with:

session.query(User).join(...
or
session.query(User).options(joinedLoad(...

Anyone could help ?

Thanks for your time,

Pierre

like image 505
Pierre Roth Avatar asked Jan 13 '11 12:01

Pierre Roth


2 Answers

session.query(User).join((Group, User.groups)) \
    .join((Department, Group.departments)).filter(Department.name == 'R&D')

This also works, but uses a sub-select:

session.query(User).join((Group, User.groups)) \
    .filter(Group.departments.any(Department.name == 'R&D'))
like image 70
Maxim Sloyko Avatar answered Oct 10 '22 03:10

Maxim Sloyko


Why don't you create a table relationships?

After implementing it, to obtain your desired:

list_of_rnd_users = [u for u in Users if 'R&D' in u.departments]

where the .departments attribute would be a property to your relationship.

like image 26
Mark Avatar answered Oct 10 '22 01:10

Mark