Pregunta

Estoy tratando de generar una consulta y que tienen dificultad en encontrar la manera más eficiente de hacerlo en sqlalchemy, (nota: estoy usando matraz sqlalchemy)

El objetivo es encontrar a todos los usuarios tienen un encuentro con un usuario específico.

Así que vamos a decir Frank tiene 10 reuniones próximamente, quiero generar una lista de todas las personas que frank tiene una reunión con.

Aquí están mis modelos:

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") 

Esto es lo que he intentado:

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

Me parece que no se cómo me podría usar combinaciones para obtener estos datos.Cualquier ayuda se agradece!

¿Fue útil?

Solución

Usted necesita para unirse a la UserMeeting tabla con la misma, utilizando meeting_id como la clave de combinación.Usted puede necesitar alias de la tabla con el fin de hacer referencia a ella dos veces.No sé si puedo escribir el sqlalchemy sintaxis para que la parte superior de mi cabeza, pero el sql parece:

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;

Y 1 es Frank.

Ah, y obtener la información del usuario también.Probablemente, usted podría terminar con User los objetos directamente de hacerlo en 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;

Otros consejos

Aquí está la versión SQLALCHEMY de la consulta para referencia:

#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()

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top