SQLAlchemy查询哪一行可能不存在

时间:2017-02-05 20:18:22

标签: python sql database sqlalchemy

我正在为公司及其子公司的数据库实施一些搜索功能。对于每个公司,可能有多个子公司或没有。每个子公司都有一个company_id列,将其链接到父公司表的id列。

以下是按名称搜索公司的示例:

def search_by_company_name(name):
    company_search = session.query(Company.name).filter(Company.name.like('%{}%'.format(name)))
    return company_search.all()

我想要的是能够通过不仅搜索其名称而且还搜索可能共享相似名称的任何子公司的名称来查询公司。我现在拥有的是:

def search_by_company_and_subsidiary_name(name):
    company_search = session.query(Company.name).filter(Company.name.like('%{}%'.format(name)) | Subsidiary.name.like('%{}%'.format(name)))
    search_results = company_search.filter(Company.id == Subsidiary.company_id)
    return search_results.all()

我的方法存在的问题是,如果某个母公司没有子公司,那么即使名称搜索与公司表中的一行匹配,查询也不会返回任何内容。

例如:

search_by_company_name('accenture')
>>> [('Accenture',)]

然而

search_by_company_and_subsidiary_name('accenture')
>>> []

我确信第二个函数返回[],因为我的数据库中没有Accenture的子公司,所以谓词.filter(Subsidiary.company_id == Company.id)实际上删除了在Company表中已找到的任何结果。我认为解决方案可能是做一些像左连接这样的事情,但经过一段时间的故障排除后我没有运气。

有没有一种很好的方法在SQLAlchemy中执行这样的查询,当给定公司的子公司表中没有匹配的行时,仍会返回在某个表中找到的所有行?

1 个答案:

答案 0 :(得分:3)

您可以考虑实施外连接而不是严格的过滤条件,例如:类似的东西:

def search_by_company_and_subsidiary_name(name):
    return session.query(Company)
                  .outerjoin(Subsidiary, Company.id == Subsidiary.company_id)
                  .filter(Company.name.like('%{}%'.format(name)) | Subsidiary.name.like('%{}%'.format(name)))
                  .all()