【问题标题】:How to create multiple-sub "where" "in" queries in flask_sqlalchemy or SQLAlchemy?如何在烧瓶 sqlalchemy 或 SQLAlchemy 中创建多子“where”“in”查询?
【发布时间】:2021-04-11 13:31:16
【问题描述】:

我是 SQLAlchemy 的新手,所以如果问题没有正确表达,请多多包涵。

但我有一个特别的问题想解决。 假设我们有一个父母、孩子和玩具桌。我们在家庭-父母、亲子和儿童玩具之间建立了 m2m 关系。

现在,如果我们想收集所有有玩具的家庭(孩子可以是父母家庭和祖父母家庭的一部分),我们会这样做:

select * from family where parent_id in ( select parent_id from parent where child_id in (select child_id from child where toy_id in (1,2)))

我想将其转换为 SQLAlchemyflask_sqlalchemy 查询。 我知道的一种方法是做类似的事情:

Toy.query.filter(Toy.id.in_((1, 2))).all()

或者在纯 SQLAlchemy 中:

session.query(Toy).filter(Toy.id.in_((1, 2))).all()

然后将输出放入列表推导式中,并将列表用作另一个 where in 的输入。

但这感觉非常低效,因为查询将在每个过滤器/列表理解创建时进行评估。

有什么方法可以在单个 flask_sqlalchemy 或纯 SQLAlchemycommand 中使用此查询,这样它只能被评估一次?

提前感谢您的帮助!

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    尝试使用子查询:

    ch = session.query(Child.child_id).filter(Child.toy_id.in_([1,2])).subquery('ch')
    p = session.query(Parent.parent_id).filter(Parent.child_id.in_(ch)).subquery('p')
    result = session.query(Family).filter(Family.parent_id.in_(p)).all()
    

    【讨论】:

    • 谢谢!这正是我想要的!
    【解决方案2】:

    您实际上可以创建一个 filter_list,然后按照您的描述立即执行查询

    filter_list = list()
    filter_list.append(Child.toy_id.in_([1,2]))
    filter_list.append(Child.toy_id.in_([4,5]))  # some other condition...
    # more conditions here...
    result = session.query(Child).filter(*filter_list).all()
    

    *filter_list 语法自动应用您附加到 filter_list 的所有条件

    【讨论】:

    • 虽然这在技术上是正确的(和 pythonic),但计算发生在 python 端而不是 db 端。通过子查询将计算(和内存成本)转移到您的数据库端将显着提高性能。
    • 我有理由相信这是不正确的,因为我可以打印此语句创建的 sql 查询:result = session.query(Child).filter(*filter_list)(请注意 .all() 丢失),它包括 where 语句,如任何本机 sql 查询(由 db 执行)都会。我猜您将 sqlalchemy .filter() 语句与 python 标准库 .filter() 方法混淆了? session.query().filter() 都在 sqlalchemy 数据库抽象层库上工作。
    • 好点,.filter() 是一个 sql 命令,而不是 python 本机。我的评论更多是针对过滤器语句的创建和存储(例如:Child.toy_id.in_([1,2]))--> 如果这些语句依赖于其他 sql 查询和/或变大,性能将开始受到影响。最好在数据库端使用 orm 在 sql 中执行这些操作。
    • 使用ORM,你检查过文档吗? docs.sqlalchemy.org/en/14/orm/query.html。这些方法只是查询构建器(ORM 级别的 SQL 构造对象),所有的 sql 显然都发生在 db 端。我真的不认为这样做会影响 python 方面的性能,或者至少它确实是 sqlalchemy 的本意......
    • 公平积分。并感谢您将我指向文档。让我给他们更深入的阅读。
    猜你喜欢
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    相关资源
    最近更新 更多