【问题标题】:SQLAlchemy query where one row may not exist一行可能不存在的 SQLAlchemy 查询
【发布时间】:2017-02-05 20:18:22
【问题描述】:

我正在为公司及其子公司的数据库实现一些搜索功能。每个公司可能有多个子公司,也可能没有。每个子公司都有一个 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()

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

例如:

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

然而

search_by_company_and_subsidiary_name('accenture')
>>> []

我确定第二个函数正在返回 [],因为我的数据库中没有 Accenture 的子公司,因此谓词 .filter(Subsidiary.company_id == Company.id) 实质上是删除了 Company 表中已找到的所有结果。我认为解决方案可能是执行左连接之类的操作,但在故障排除一段时间后我没有任何运气。

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

【问题讨论】:

    标签: python sql database sqlalchemy


    【解决方案1】:

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

    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()
    

    【讨论】:

    • 经过一番挖掘,这实际上正是我最终所做的,感谢您的回答!
    • 很高兴阅读扎克。如果您能接受答案,将不胜感激。 :)
    猜你喜欢
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2017-05-13
    相关资源
    最近更新 更多