在sqlalchemy中按顺序查询子查询

时间:2015-10-14 19:49:03

标签: python sqlalchemy subquery flask-sqlalchemy

我在sqlalchemy查询中需要一些帮助。 我在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.

1 个答案:

答案 0 :(得分:2)

您的问题是,.count()会返回intlong而非子查询。

为了做你想要做的事,你必须像这样做

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__)
    )
)

correlate()调用告诉SQLAlchemy不要尝试将UserRecordCard放入子选择的from子句中,而是从周围的select中取出它。

您可能需要或不必在子查询中使用aliasscalar,我不记得了。一般的想法应该成立。