非单例集合的热切加载

发布于 2024-12-20 04:31:24 字数 381 浏览 2 评论 0原文

我想加载重复对象的集合。我的模型如下所示:

Item -> Identifier

我想(热切地)加载共享相同标识符的项目集合,但忽略包含一个或更少项目的绝大多数集合。 ORM 关系是双向设置的(Identifier.items 和 Item.identifier)。 SQL 应该看起来像这样:

SELECT * FROM Item WHERE identifier_id IN (
    SELECT identifier_id FROM Item GROUP BY identifier_id HAVING COUNT(*) > 1)

I'd like to load collections of repeated objects. My model looks like this:

Item -> Identifier

I'd like to load (eagerly) collections of Items that share the same Identifier, but ignore the vast majority of collections that contain one item or less. The ORM relationship is set up in both directions (Identifier.items and Item.identifier). The SQL should look like something like this:

SELECT * FROM Item WHERE identifier_id IN (
    SELECT identifier_id FROM Item GROUP BY identifier_id HAVING COUNT(*) > 1)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三生路 2024-12-27 04:31:24

使用子查询,可以通过以下方式实现:

q = (select([Item.identifier_id, func.count(Item.id).label("cnt")]).
     group_by(Item.identifier_id).having(func.count(Item.id)>1)).alias("subq")
qry =  (session.query(Item).join(q, Item.identifier_id==q.c.identifier_id))
print qry # prints SQL statement generated
items = qry.all() # result

Using a sub-query, this can be achieved as following:

q = (select([Item.identifier_id, func.count(Item.id).label("cnt")]).
     group_by(Item.identifier_id).having(func.count(Item.id)>1)).alias("subq")
qry =  (session.query(Item).join(q, Item.identifier_id==q.c.identifier_id))
print qry # prints SQL statement generated
items = qry.all() # result
一向肩并 2024-12-27 04:31:24

这是我最终使用的版本:(

from sqlalchemy.sql.functions import count
from sqlalchemy.orm import subqueryload
# …

repeats = (
    select(
        (Item.identifier,
        count(Item.identifier)))
    .group_by(Item.identifier)
    .having(count(Item.identifier) > 1)
    .alias())
for identifier in (
    sess.query(Identifier)
        .join(repeats, repeats.c.identifier==Identifier.value)
        .options(subqueryload(Identifier.items))
):
    for item in identifier.items:
        pass

标识符现在映射到选择,并且不受数据库表支持,这也使得导入速度更快)

Here is the version I am finally using:

from sqlalchemy.sql.functions import count
from sqlalchemy.orm import subqueryload
# …

repeats = (
    select(
        (Item.identifier,
        count(Item.identifier)))
    .group_by(Item.identifier)
    .having(count(Item.identifier) > 1)
    .alias())
for identifier in (
    sess.query(Identifier)
        .join(repeats, repeats.c.identifier==Identifier.value)
        .options(subqueryload(Identifier.items))
):
    for item in identifier.items:
        pass

(Identifier is now mapped against a select and not backed by a database table, which makes import a bit faster too)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文