我有一个如下所示的消息表,如何为特定用户获取消息,即用一个用户获取一条最新消息。例如, 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))
答案 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)