SQLAlchemy最新项目

时间:2013-01-31 21:13:02

标签: python sqlalchemy

这应该很简单,但我似乎无法弄明白。

这是我的表:

class UserEvent(Base):
    __tablename__ = 'user_events'

    user_id = Column(Integer, ForeignKey('users.user_id'),
                            primary_key=True, nullable=False)
    event_time = Column(DateTime, primary_key=True, nullable=False)
    detect_time = Column(DateTime, nullable=False)
    new_state = Column(Boolean, nullable=False)

以下是一些示例数据:

+---------+---------------------+---------------------+-----------+
| user_id | event_time          | detect_time         | new_state |
+---------+---------------------+---------------------+-----------+
|       1 | 2012-11-12 16:12:00 | 2013-01-31 20:55:31 |         1 |
|       1 | 2012-11-12 18:24:00 | 2013-01-31 20:55:33 |         0 |
+---------+---------------------+---------------------+-----------+

我想为每个user_id找到最新的(event_time)UserEvent。

我试过这个:

for event, current in session.query(
        UserEvent, func.max(UserEvent.event_time)).group_by(
            UserEvent.user_id):

查询返回正确的“事件”(2012-11-12 18:24:00)。但是,JOINED不正确(或其他)因为“current”为True。

无论表中有多少行,我总是会回到最近的event_time和OLDEST new_state。

1 个答案:

答案 0 :(得分:2)

您使用的是MySQL吗?该特定表达式将生成查询:

SELECT
    user_events.user_id,
    user_events.event_time,
    user_events.detect_time,
    user_events.new_state,
    max(user_events.event_time)
FROM
    user_events
GROUP BY
    user_events.user_id

在大多数数据库中都是无效的,但是给你一个随机的MySQL行。您可以从http://news.ycombinator.com/item?id=5122798找到更多关于行为的信息(巧合的是,由SQLAlchemy的作者撰写)

这个表达式可行:

for user_id, current in session.query(
    UserEvent.user_id, func.max(UserEvent.event_time)).group_by(
        UserEvent.user_id):

虽然它返回user_id而不是UserEvent的实例。

这样的东西可能会给你想要的东西:

t = session.query(
    UserEvent.user_id,
    func.max(UserEvent.event_time).label('max_time'),
).group_by(
    UserEvent.user_id,
).subquery().alias('t')

query = session.query(
    UserEvent,
).filter(and_(
    UserEvent.user_id == t.c.user_id,
    UserEvent.event_time == t.c.max_time,
))