SQLAlchemy连接查询 - 最有效的查询方法
我正在尝试生成一个查询,但在使用sqlalchemy时遇到了一些困难(注意,我使用的是flask-sqlalchemy)。
我的目标是找到所有与特定用户有会议的用户。
比如说,Frank有10个即将到来的会议,我想生成一个列表,列出所有与Frank有会议的人。
这是我的模型:
class UserMeeting(db.Model):
""" Associative table, links meetings to users in a many to many fashion"""
__tablename__ = 'userMeeting'
id = db.Column(db.Integer, primary_key = True)
meeting_id = db.Column(db.Integer, db.ForeignKey('meeting.id'), primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
class Meeting(db.Model):
__tablename__ = "meeting"
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(128))
#... other columns
#associative reference
attendees = db.relationship('UserMeeting', backref='meeting')
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key = True)
email = db.Column(db.String(128), index=True, unique=True)
password = db.Column(db.String(128))
#associative reference
attendingMeetings = db.relationship("UserMeeting", backref="user", cascade="all, delete-orphan")
这是我尝试过的:
#Assume frank's a user with id == 1
frank = User.query.get(1)
franks_meetings = Meeting.query.join(Meeting.attendees).filter(UserMeeting.user == frank).all()
#not efficient way of getting users in meetings with frank
users = []
for meeting in franks_meetings:
for userMeeting in meeting.attendees:
if userMeeting.user != frank:
users.append(userMeeting.user)
#is there a way to just generate one query and get this data?
我似乎不太明白如何使用连接(joins)来获取这些数据。任何帮助都将不胜感激!
2 个回答
1
这里是这个查询的sqlalchemy版本,供参考:
#get all users in meetings with Frank, (frank.id == 1)
um = aliased(UserMeeting)
frank = User.query.get(1)
q = session.query(User).join(User.attendingMeetings).\
filter(UserMeeting.meeting_id == um.meeting_id).\
filter(UserMeeting.user_id != frank.id, um.user_id == frank.id)
users_meeting_with_frank = q.all()
1
你需要把UserMeeting这个表和它自己连接起来,使用meeting_id作为连接的关键。你可能需要给这个表起个别名,这样才能两次引用它。我现在不太记得怎么用sqlalchemy写这个语法,但sql的样子是这样的:
select distinct(b.user_id) as other_user_id
from usermeeting a
inner join usermeeting b
on a.meeting_id=b.meeting_id
where a.user_id=1 and b.user_id != 1;
还有,1
是Frank。
哦,对了,还需要获取用户的详细信息。你可以通过在sqlalchemy中这样做,直接得到User
对象:
select distinct(u.id), u.email
from usermeeting a
inner join usermeeting b
on a.meeting_id=b.meeting_id
inner join users u
on b.user_id=u.id
where a.user_id=1 and b.user_id != 1;