繁体   English   中英

更改where子句而不在SQLAlchemy中生成子查询

[英]Changing where clause without generating subquery in SQLAlchemy

我正在尝试构建一个相对复杂的查询,并希望直接操作结果的where子句,而无需克隆/子查询返回的查询。 一个例子如下:

    session = sessionmaker(bind=engine)()

    def generate_complex_query():
        return select(
            columns=[location.c.id.label('id')], 
            from_obj=location,
            whereclause=location.c.id>50
        ).alias('a')

    query = generate_complex_query()
    # based on this query, I'd like to add additional where conditions, ideally like:
    # `query.where(query.c.id<100)`
    # but without subquerying the original query

    # this is what I found so far, which is quite verbose and it doesn't solve the subquery problem
    query = select(
        columns=[query.c.id],
        from_obj=query,
        whereclause=query.c.id<100
    )

    # Another option I was considering was to map the query to a class:
    #   class Location(object):pass
    #   mapper(Location, query)
    #   session.query(Location).filter(Location.id<100)
    # which looks more elegant, but also creates a subquery

    result = session.execute(query)

    for r in result:
        print r

这是生成的查询:

SELECT a.id 
FROM (SELECT location.id AS id 
FROM location 
WHERE location.id > %(id_1)s) AS a 
WHERE a.id < %(id_2)s

我想获得:

SELECT location.id AS id 
FROM location 
WHERE id > %(id_1)s and
id < %(id_2)s

有什么办法可以做到这一点? 这样做的原因是,我想查询(2)稍快(不要太多),以及映射器的例子(上面第二个示例),我有地方搅乱标签( id变成anon_1_ida.id ,如果我的名字别名)。

你为什么不这样做:

query = generate_complex_query()
query = query.where(location.c.id < 100)

本质上,您可以像这样优化任何查询。 另外,我建议阅读《 SQL Expression Language Tutorial》 ,它非常出色,并介绍了您需要的所有技术。 建立select方法只是一种方法。 通常,我会这样构建查询: select(column).where(expression).where(next_expression) ,依此类推。 通常,SQLAlchemy会从上下文自动推断FROM ,即您几乎不需要指定它。

由于您无权访问generate_complex_query的内部,请尝试以下操作:

query = query.where(query.c.id < 100)

我认为这应该在您的情况下有效。

另一个想法:

query = query.where(text("id < 100"))

这使用SQLAlchemy的文本表达式。 但是,这可能对您有用,这很重要 :如果您想引入变量,请阅读上面链接的API的描述,因为仅使用绑定参数中间的格式字符串将使您可以进行SQL注入,这通常是精通SQLAlchemy,但如果使用此类文字表达式,则必须小心。

还要注意,这是可行的,因为您将列标记为id 如果您不这样做并且不知道列名,那么这也不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM