如何通过三个多对多关系在sqlalchemy中进行查询,加入它们并获取唯一的记录?
我的设置如下:
参见代码:
#!/usr/bin/python3
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import (
Column,
Integer,
ForeignKey
)
from sqlalchemy.orm import (
relationship,
backref
)
Base = declarative_base()
class Command(Base):
__tablename__ = 'commands'
id = Column(Integer, primary_key=True)
users = relationship('User', secondary='users_commands')
groups = relationship('Group', secondary='groups_commands')
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
groups = relationship('Group', secondary='users_groups')
commands = relationship('Command', secondary='users_commands')
class Group(Base):
__tablename__ = 'groups'
id = Column(Integer, primary_key=True)
users = relationship('User', secondary='users_groups')
commands = relationship('Command', secondary='groups_commands')
class UserGroup(Base):
"""Many-To-Many on users and groups"""
__tablename__ = 'users_groups'
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
group_id = Column(Integer, ForeignKey('groups.id'), primary_key=True)
user = relationship('User', backref=backref('user_groups', cascade='all, delete-orphan'))
user_group = relationship('UserGroup', backref=backref('user_groups', cascade='all, delete-orphan'))
class UserCommand(Base):
"""Many-to-many on users and commands"""
__tablename__ = 'users_commands'
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
command_id = Column(Integer, ForeignKey('commands.id'), primary_key=True)
user = relationship('User', backref=backref('user_commands', cascade='all, delete-orphan'))
command = relationship('Command', backref=backref('user_commands', cascade='all, delete-orphan'))
class GroupCommand(Base):
"""Many-to-many on groups and commands"""
__tablename__ = 'groups_commands'
group_id = Column(Integer, ForeignKey('groups.id'), primary_key=True)
command_id = Column(Integer, ForeignKey('commands.id'), primary_key=True)
group = relationship('Group', backref=backref('group_commands', cascade='all, delete-orphan'))
command = relationship('Command', backref=backref('group_commands', cascade='all, delete-orphan'))
我希望为一个用户获取所有命令,首先是基于用户所在的组,然后是基于用户特定的命令。例如。伪代码:
我可以通过两个单独的查询和列表/设置唯一连接来完成:
commands_user_specific = session.query(Command).\
join(Command.users).\
join(User.groups).\
filter(User.id == self.user.id).all()
commands_group_specific = session.query(Command).\
join(Command.groups).\
join(Group.users).\
filter(User.id == self.user.id).all()
commands = commands_user_specific +\
list(set(commands_group_specific) - set(commands_user_specific))
但是我相信还有一些更优雅的方式,“。join”或者甚至通过“.filter”,我更喜欢使用它。
感谢您的见解