[英]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_id
或a.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.