SQLAlchemy中的order by子查询

3
我可以帮助您进行SQLAlchemy查询的翻译。 我在实现这个MySQL查询时遇到了麻烦。
MySQL查询:
select u.post_id
from
    user_record_cards u
where
    u.record_card_id = 1 and u.count = 1
order by (select 
        count(*)
    from
        post_likes p
    where
        p.post = u.post_id)

我的SQLAlchemy查询如下:

obj = (
    UserRecordCard.query
    .filter(
        UserRecordCard.record_card_id == 1,
        UserRecordCard.count == 1
    ).order_by(
        Like.query.filter(
            Like.post == UserRecordCard.post_id
        ).count()
    ).all()
)

我的追踪信息如下:

Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/elements.py", line 3453, in _literal_as_text
    "SQL expression object or string expected."
ArgumentError: SQL expression object or string expected.

http://stackoverflow.com/help/mcve -- 你需要什么帮助?展示代码、你得到的输出和你想要的输出。 - Prune
@Prune,现在我已经添加了我的SQLAlchemy和traceback!希望能有所帮助! - pirate
我们正在接近解决问题了;那么,你的代码中哪一行有问题呢?你尝试过简化代码以将问题点与好的部分分离吗?我不熟悉SQLalchemy的差异,所以我必须引导你,而不是自己解决问题。 - Prune
问题出在order_by子查询中").order_by(Like.query.filter(Like.post == UserRecordCard.post_id).count()",如果您知道如何在SQLAlchemy中实现子查询,我将不胜感激,因为我在谷歌上找不到任何相关的好链接! - pirate
1个回答

2
你遇到的问题是.count()返回的是一个int或者long类型而不是子查询。
为了达到你想要的效果,你需要像这样操作。
from sqlalchemy import select, func

obj = (
    UserRecordCard.query
    .filter(
       UserRecordCard.record_card_id == 1,
       UserRecordCard.count == 1
    )
    .order_by(
        select([
            func.count()
        ])
        .select_from(Like.__table__)
        .where(Like.post == UserRecordCard.post_id)
        .correlate(UserRecordCard.__table__)
    )
)
< p > correlate() 调用告诉 SQLAlchemy 不要尝试将 UserRecordCard 放入子查询的 from-clause 中,而是从周围的 select 中获取它。

您可能需要在子查询上使用 aliasscalar,我记不清了。但是一般的想法应该保持不变。


谢谢伙计!这正是我寻找的,它工作得像魅力一样! - pirate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接