SQLAlchemy与或

时间:2015-11-06 03:54:57

标签: python flask sqlalchemy

我让自己陷入困境与一些平坦的事情我试图锻炼身体。我有一个旧的网络应用程序,我试图开始,并决定从头开始重写它。作为其中的一部分,我正在玩SQL Alchemy并尝试提高我的pythonic技能 - 所以我有一个搜索对象,我试图运行,我在那里查看如果客户查询存在于帐户名称和客户名称字段中,则与其中任何一个匹配。但是,SQL Alchemy将其注册为AND 如果我添加了额外的or_块,则无法识别它们并进行适当的处​​理。

我已将其移动,因此它是第一个查询,但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 个答案:

答案 0 :(得分:2)

filter子句应该是:

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)

答案 1 :(得分:1)

更简单的方法是使用“|”的OR子句如果您想查找包含您正在搜索的一个或多个单词的所有匹配项,则匹配中的运算符,例如

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