Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy-WHERE子句中的子查询_Python_Sqlalchemy_Subquery - Fatal编程技术网

Python SQLAlchemy-WHERE子句中的子查询

Python SQLAlchemy-WHERE子句中的子查询,python,sqlalchemy,subquery,Python,Sqlalchemy,Subquery,我最近刚开始使用SQLAlchemy,但仍然难以理解其中的一些概念 归结到基本元素,我有两张这样的表(这是通过炼金术实现的): 我将如何查询用户列表及其最新帖子(不包括没有帖子的用户)。如果我使用的是SQL,我会: SELECT [whatever] FROM posts AS p LEFT JOIN users AS u ON u.user_id = p.user_id WHERE p.post_time = (SELECT MAX(post_time) FROM posts WHER

我最近刚开始使用SQLAlchemy,但仍然难以理解其中的一些概念

归结到基本元素,我有两张这样的表(这是通过炼金术实现的):

我将如何查询用户列表及其最新帖子(不包括没有帖子的用户)。如果我使用的是SQL,我会:

SELECT [whatever]
FROM posts AS p
    LEFT JOIN users AS u ON u.user_id = p.user_id
WHERE p.post_time = (SELECT MAX(post_time) FROM posts WHERE user_id = u.user_id)
因此,我确切地知道“期望的”SQL以获得我想要的效果,但不知道如何在SQLAlchemy中“正确地”表达它

编辑:如果这很重要,我使用的是SQLAlchemy 0.6.6。

这应该有效(不同的SQL,相同的结果):

其中c代表“列”


前面的答案是可行的,但您要求的确切sql也是按照实际语句编写的:

print s.query(User, Posts).\
    outerjoin(Posts.user).\
    filter(Posts.post_time==\
        s.query(
            func.max(Posts.post_time)
        ).
        filter(Posts.user_id==User.user_id).
        correlate(User).
        as_scalar()
    )
我猜不一定很明显的“概念”是,目前需要使用as_scalar()将子查询建立为“标量”(根据上下文,它可能应该假设为针对==)

编辑:确认,这是有轨电车的行为,已完成检票#2190。在当前tip或0.7.2版中,自动调用as_scalar(),上述查询可以是:

print s.query(User, Posts).\
    outerjoin(Posts.user).\
    filter(Posts.post_time==\
        s.query(
            func.max(Posts.post_time)
        ).
        filter(Posts.user_id==User.user_id).
        correlate(User)
    )

它的表达方式通常类似于实际的SQL—您创建了一个返回单个结果的子查询并与之进行比较—然而,有时真正痛苦的是,如果您必须在子查询中使用您已经查询或加入的表

解决方案是在子查询中创建要引用的模型的别名版本

假设您已经在一个连接中运行,其中有一个现有的
帖子
模型
和一些基本的
查询
就绪-现在,您想查询每个用户的最新(单个)帖子列表,您可以按如下方式过滤查询:

from sqlalchemy.orm import aliased
posts2 = aliased(Posts) # create aliased version

query = query.filter(
    model.post_id
    ==
    Posts.query # create query directly from model, NOT from the aliased version!
        .with_entities(posts2.post_id) # only select column "post_id"
        .filter(
            posts2.user_id == model.user_id
        )
        .order_by(posts2.post_id.desc()) # assume higher id == newer post
        .limit(1) # we must limit to a single row so we only get 1 value
)

我故意不使用<代码> FUNC.MAX < /Cord>,因为我认为这是一个简单的版本,并且已经有了其他答案,我想这个例子对于那些通常会发现这个问题的人来说是有用的,因为他们正在寻找一个如何对同一个表进行子查询的解决方案。

print s.query(User, Posts).\
    outerjoin(Posts.user).\
    filter(Posts.post_time==\
        s.query(
            func.max(Posts.post_time)
        ).
        filter(Posts.user_id==User.user_id).
        correlate(User)
    )
from sqlalchemy.orm import aliased
posts2 = aliased(Posts) # create aliased version

query = query.filter(
    model.post_id
    ==
    Posts.query # create query directly from model, NOT from the aliased version!
        .with_entities(posts2.post_id) # only select column "post_id"
        .filter(
            posts2.user_id == model.user_id
        )
        .order_by(posts2.post_id.desc()) # assume higher id == newer post
        .limit(1) # we must limit to a single row so we only get 1 value
)