2015-11-06 78 views
0

我正在與一些sqlalchemy綁在一起,我試圖解決。我有一箇舊的Web應用程序,我正在嘗試啓動,並決定從頭開始重寫它。作爲其中的一部分,我正在玩SQL鍊金術,並試圖提高我的pythonic技能 - 所以我有一個搜索對象,我試圖運行,在那裏我檢查客戶查詢是否存在帳戶名稱和客戶姓名字段,並與其中任何一個匹配。但是,SQL Alchemy將它註冊爲AND如果我添加額外的or_ blocks,它將無法識別它們並正確處理。SQLAlchemy匹配或

我已經移動它,因此它是第一個查詢,但sqlalchemy中的查詢計劃器使它完全一樣。

任何想法?

def CustomerCountryMatch(query, page): 
    customer=models.Customer 
    country=models.CustomerCodes 
    query=customer.query.order_by(customer.account_name).\ 
     group_by(customer.account_name).having(func.max(customer.renewal_date)).\ 
     join(country, customer.country_code==country.CODE).\ 
     add_columns(customer.account_name, 
      customer.customer_name, 
      customer.account_id, 
      customer.CustomerNote, 
      country.COUNTRY, 
      country.SupportRegion, 
      customer.renewal_date, 
      customer.contract_type, 
      customer.CCGroup).\ 
     filter(customer.account_name.match(query)).filter(or_(customer.customer_name.match(query))).\ 
     paginate(page, 50, False) 

作爲查詢執行低於:

sqlalchemy.engine.base.Engine SELECT customer.customer_id AS customer_customer_id, 
customer.customer_code AS customer_customer_code, 
customer.address_code AS customer_address_code, 
customer.customer_name AS customer_customer_name, 
customer.account_id AS customer_account_id, 
customer.account_name AS customer_account_name, 
customer.`CustomerNote` AS `customer_CustomerNote`, 
customer.renewal_date AS customer_renewal_date, 
customer.contract_type AS customer_contract_type, 
customer.country_code AS customer_country_code, 
customer.`CCGroup` AS `customer_CCGroup`, 
customer.`AgentStatus` AS `customer_AgentStatus`, 
customer.comments AS customer_comments, 
customer.`SCR` AS `customer_SCR`, 
customer.`isDummy` AS `customer_isDummy`, 
customer_codes.`COUNTRY` AS `customer_codes_COUNTRY`, 
customer_codes.`SupportRegion` AS `customer_codes_SupportRegion` 
FROM customer INNER JOIN 
customer_codes ON customer.country_code=customer_codes.`CODE` WHERE 
MATCH (customer.account_name) AGAINST (%s IN BOOLEAN MODE) AND 
MATCH (customer.customer_name) AGAINST (%s IN BOOLEAN MODE) GROUP BY 
customer.account_name HAVING max(customer.renewal_date) ORDER BY 
customer.account_name LIMIT %s, 
%s 2015-11-06 03:32:52,035 INFO sqlalchemy.engine.base.Engine ('bob', 'bob', 0, 50) 

回答

2

濾波器子句應該是:

filter(
    or_(
     customer.account_name.match(query), 
     customer.customer_name.match(query) 
    ) 
) 

調用filter兩次,如在filter(clause1).filter(clause2)使用AND(見docs加入標準)。

構造:filter(clause1).filter(or_(clause2))不會做你想要的,並且被翻譯成SQL:clause1 AND clause2

以下示例是有意義的:filter(clause1).filter(or_(clause2, clause3)),並將其翻譯爲SQL:clause1 AND (clause2 OR clause 3)

+0

謝謝@codeape - 我沒有意識到你可以使用該語法。非常感謝 – Scott

0

更簡單的方法是使用OR子句,使用'|'如果你想找到包含一個或多個正在搜索的單詞的所有匹配,例如:

query = query.filter(Table.text_searchable_column.match('findme | orme'))