sqlalchemy 2.x带有特定列的sqlalchemy 2.x使标量()返回非符号对象

发布于 2025-02-11 19:56:59 字数 1329 浏览 1 评论 0 原文

这个问题可能是我不了解(新)sqlalchemy的体系结构,通常我使用这样的代码:

query = select(models.Organization).where(
    models.Organization.organization_id == organization_id
)
result = await self.session.execute(query)

return result.scalars().all()

工作正常,我会得到模型列表(如果有)。

只有带有特定列的查询:

query = (
    select(
        models.Payment.organization_id,
        models.Payment.id,
        models.Payment.payment_type,
    )
    .where(
        models.Payment.is_cleared.is_(True),
    )
    .limit(10)
)

result = await self.session.execute(query)

return result.scalars().all()

我只获得第一行,仅第一列。似乎也一样:

到目前为止,我的理解是,在新的SQLalchemy中,我们应该始终致电 scalars scalars ()在查询上,如下所述: https://docs.sqlalchemy.org/en/14/changelog/migration_20.html#migration-migration-orm-usage

但是,对于特定的列,似乎我们完全不能使用标量()。更令人困惑的是 result.scalars()返回 sqlalchemy.engine.result.scalarresult 具有fetchmany()以任何有意义的方式迭代。

我的问题是,我不明白什么?

This question is probably me not understanding architecture of (new) sqlalchemy, typically I use code like this:

query = select(models.Organization).where(
    models.Organization.organization_id == organization_id
)
result = await self.session.execute(query)

return result.scalars().all()

Works fine, I get a list of models (if any).

With a query with specific columns only:

query = (
    select(
        models.Payment.organization_id,
        models.Payment.id,
        models.Payment.payment_type,
    )
    .where(
        models.Payment.is_cleared.is_(True),
    )
    .limit(10)
)

result = await self.session.execute(query)

return result.scalars().all()

I am getting first row, first column only. Same it seems to: https://docs.sqlalchemy.org/en/14/core/connections.html?highlight=scalar#sqlalchemy.engine.Result.scalar

My understanding so far was that in new sqlalchemy we should always call scalars() on the query, as described here: https://docs.sqlalchemy.org/en/14/changelog/migration_20.html#migration-orm-usage

But with specific columns, it seems we cannot use scalars() at all. What is even more confusing is that result.scalars() returns sqlalchemy.engine.result.ScalarResult that has fetchmany(), fechall() among other methods that I am unable to iterate in any meaningful way.

My question is, what do I not understand?

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

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

发布评论

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

评论(1

从来不烧饼 2025-02-18 19:56:59

到目前为止,我的理解是,在新的sqlalchemy中,我们应该始终在查询上调用标量()

,这主要是正确的,但仅用于返回整个ORM对象的查询。只有一个常规 .execute()

    query = select(Payment)

    results = sess.execute(query).all()
    print(results)  # [(Payment(id=1),), (Payment(id=2),)]
    print(type(results[0]))  # <class 'sqlalchemy.engine.row.Row'>

返回对象的列表,每个列表包含一个ORM对象。用户发现尴尬,因为他们需要从 row 对象解开ORM对象。因此,现在建议使用 .scalars()

    results = sess.scalars(query).all()
    print(results)  # [Payment(id=1), Payment(id=2)]
    print(type(results[0]))  # <class '__main__.Payment'>

,对于返回单个属性(列)的查询,我们不想使用 .scalars(),因为这只会给我们每行的一列,通常是第一列

    query = select(
        Payment.id,
        Payment.organization_id,
        Payment.payment_type,
    )

    results = sess.scalars(query).all()
    print(results)  # [1, 2]

,我们要使用常规 .execute(),以便我们可以看到所有列

    results = sess.execute(query).all()
    print(results)  # [(1, 123, None), (2, 234, None)]

注:

  • .scalars()正在执行相同的事情:返回每行中包含一个(标量)值的列表(默认为index = 0)。


  • sess.scalars()是首选构造。它只是 sess.execute()。标量()

    的速记

My understanding so far was that in new sqlalchemy we should always call scalars() on the query

That is mostly true, but only for queries that return whole ORM objects. Just a regular .execute()

    query = select(Payment)

    results = sess.execute(query).all()
    print(results)  # [(Payment(id=1),), (Payment(id=2),)]
    print(type(results[0]))  # <class 'sqlalchemy.engine.row.Row'>

returns a list of Row objects, each containing a single ORM object. Users found that awkward since they needed to unpack the ORM object from the Row object. So .scalars() is now recommended

    results = sess.scalars(query).all()
    print(results)  # [Payment(id=1), Payment(id=2)]
    print(type(results[0]))  # <class '__main__.Payment'>

However, for queries that return individual attributes (columns) we don't want to use .scalars() because that will just give us one column from each row, normally the first column

    query = select(
        Payment.id,
        Payment.organization_id,
        Payment.payment_type,
    )

    results = sess.scalars(query).all()
    print(results)  # [1, 2]

Instead, we want to use a regular .execute() so we can see all the columns

    results = sess.execute(query).all()
    print(results)  # [(1, 123, None), (2, 234, None)]

Notes:

  • .scalars() is doing the same thing in both cases: return a list containing a single (scalar) value from each row (default is index=0).

  • sess.scalars() is the preferred construct. It is simply shorthand for sess.execute().scalars().

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