簡體   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