SQL-алхимию присоединяйтесь к запросу - самый эффективный способ запроса

StackOverflow https://stackoverflow.com//questions/25090375

Вопрос

Я пытаюсь создать запрос и иметь трудности, найдя самый эффективный способ сделать это в SQLAlchemy, (обратите внимание, я использую Flask-sqlalchemy)

Цель состоит в том, чтобы найти всех пользователей встречаться с конкретным пользователем.

Итак, давайте скажем, Фрэнк имеет 10 встреч, которые придумывают, я хочу создать список всех людей Фрэнка, с которыми есть встреча.

Вот мои модели:

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?
.

Мне кажется, не хватает того, как я мог бы просто использовать присоединения, чтобы получить эти данные.Любая помощь будет оценена!

Это было полезно?

Решение

Вам нужно присоединиться к таблице IsermeeTing с самой компанией, используя Comment_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 является Фрэнк.

О, и получение деталей пользователей тоже.Вероятно, вы можете в конечном итоге с объектами User напрямую от этого в SQLALCHEMY:

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;
.

Другие советы

Вот версия 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()
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top