如何从 SQLAlchemy 中获取最年轻的对象?

How can I get the youngest objects from SQLAlchemy?

我的 table 中的每一行都有一个日期。日期不是唯一的。同一日期出现不止一次。 我想获取所有日期最小的对象。

我的解决方案有效,但我不确定这是否是一种优雅的 SQLAlchemy 方式。

query = _session.query(Table._date) \
            .order_by(Table._date.desc()) \
            .group_by(Table._date)
# this is the younges date (type is date.datetime)
young = query.first()

query = _session.query(Table).filter(Table._date==young)
result = query.all()

有没有办法将所有这些放在一个查询对象或类似的对象中?

你需要一个having clause,你需要导入max函数 那么您的查询将是:

from sqlalchemy import func

stmt = _session.query(Table) \
               .group_by(Table._date) \
               .having(Table._date == func.max(Table._date)

这会生成如下所示的 sql 语句。

SELECT my_table.* 
FROM my_table 
GROUP BY my_table._date 
HAVING my_table._date = MAX(my_table._date)

如果您使用 select 构建 sql 语句,您可以检查在您的案例中生成的 sql 使用。 *我不确定这是否适用于语句 query

str(stmt)

使用子查询执行此操作的两种方法:

# @note: do not need to alias, but do in order to specify `name`
T1 = aliased(MyTable, name="T1")

# version-1:
subquery = (session.query(func.max(T1._date).label("max_date"))
            .as_scalar()
            )
# version-2:
subquery = (session.query(T1._date.label("max_date"))
            .order_by(T1._date.desc())
            .limit(1)
            .as_scalar()
            )

qry = session.query(MyTable).filter(MyTable._date == subquery)
results = qry.all()

输出应该类似于:

# version-1
SELECT my_table.id AS my_table_id, my_table.name AS my_table_name, my_table._date AS my_table__date
FROM my_table
WHERE my_table._date = (
    SELECT max("T1"._date) AS max_date
    FROM my_table AS "T1")

# version-2
SELECT my_table.id AS my_table_id, my_table.name AS my_table_name, my_table._date AS my_table__date
FROM my_table
WHERE my_table._date = (
    SELECT "T1"._date AS max_date
    FROM my_table AS "T1"
    ORDER BY "T1"._date DESC LIMIT ? OFFSET ?
    )