查询为特定用户获取消息

时间:2014-05-06 03:15:16

标签: sql sqlalchemy fetch

我有一个如下所示的消息表,如何为特定用户获取消息,即用一个用户获取一条最新消息。例如, user1 包含的消息user2 user3 ,如何在 user1 user2 之间获取最近的一条消息, user1之间的最近一条消息 user3

class Message(Base):
    __tablename__ = 'messages'

    id = Column(Integer(), primary_key=True)
    sender_id = Column(Integer(), ForeignKey('users.id'))
    body = Column(Text())
    recipient_id = Column(Integer())
    created_at = Column(DateTime())
    updated_at = Column(DateTime())

我能想到的SQL正在关注,但这还不够。你能帮助我吗?非常感谢,:)。

session.query(Message).\
filter(or_(Message.user_id==user.id, Message.recipient_id==user.id))

2 个答案:

答案 0 :(得分:0)

尝试

from sqlalchemy import desc

session.query(Message).\
filter(or_(Message.user_id==user.id, Message.recipient_id==user.id)).\
order_by(desc(Message.created_at)).\
first()

答案 1 :(得分:0)

下面的代码应该为您提供一个示例,使用created_at作为最新的决策列。您可以轻松将其更改为updated_at 请注意,对于两个用户(A and B),它将同时返回最新消息:A->B和最新B->A中的最新消息。

from datetime import date
from sqlalchemy import create_engine, Column, Text, Integer, DateTime, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.sql import func, and_
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///:memory:', echo=True)
session = sessionmaker(bind=engine)()
Base = declarative_base(engine)

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer(), primary_key=True)
    name = Column(Text())

class Message(Base):
    __tablename__ = 'messages'

    id = Column(Integer(), primary_key=True)
    sender_id = Column(Integer(), ForeignKey('users.id'))
    body = Column(Text())
    recipient_id = Column(Integer(), ForeignKey('users.id'))
    created_at = Column(DateTime())
    updated_at = Column(DateTime())

    sender = relationship(User, backref="messages_sent", foreign_keys=sender_id)
    recipient = relationship(User, backref="messages_recv", foreign_keys=recipient_id)


Base.metadata.create_all()
users = u1, u2, u3 = [
        User(name='user1'),
        User(name='user2'),
        User(name='user3'),
        ]
session.add_all(users)

session.add_all([
    Message(sender=u1, recipient=u2, body="bod12-a", created_at = date(2014, 1, 13)),
    Message(sender=u1, recipient=u2, body="bod12-X", created_at = date(2014, 1, 3)),

    Message(sender=u2, recipient=u3, body="bod23-X", created_at = date(2014, 1, 13)),
    Message(sender=u2, recipient=u3, body="bod23-a", created_at = date(2013, 1, 13)),
    ])
session.flush()

subq = (session
        .query(Message.sender_id, Message.recipient_id,
            func.max(Message.created_at).label("max_created_at"))
        .group_by(Message.sender_id, Message.recipient_id)
        ).subquery("subq")

q = (session
        .query(Message)
        .join(subq, and_(
            Message.sender_id == subq.c.sender_id,
            Message.recipient_id == subq.c.recipient_id,
            Message.created_at == subq.c.max_created_at)
            )
        ).all()
for x in q:
    print(x.sender_id, x.recipient_id, x.body)