这个问题可能是我不理解(新)sqlalchemy 的架构,通常我使用这样的代码:
query = select(models.Organization).where(
models.Organization.organization_id == organization_id
)
result = await self.session.execute(query)
return result.scalars().all()
Run Code Online (Sandbox Code Playgroud)
工作正常,我得到了模型列表(如果有的话)。
对于仅包含特定列的查询:
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()
Run Code Online (Sandbox Code Playgroud)
我只得到第一行第一列。似乎相同: https: //docs.sqlalchemy.org/en/14/core/connections.html ?highlight=scalar#sqlalchemy.engine.Result.scalar
到目前为止,我的理解是,在新的 sqlalchemy 中,我们应该始终调用scalars()查询,如下所述:https: //docs.sqlalchemy.org/en/14/changelog/migration_20.html#migration-orm-usage
但对于特定的列,我们似乎根本不能使用 scalars() 。更令人困惑的是,result.scalars()返回sqlalchemy.engine.result.ScalarResult具有 fetchmany()、fechall() 以及其他我无法以任何有意义的方式迭代的方法。
我的问题是,我不明白什么?
Gor*_*son 16
到目前为止,我的理解是,在新的 sqlalchemy 中,我们应该始终在查询上调用 scalars()
这在很大程度上是正确的,但仅适用于返回整个 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'>
Run Code Online (Sandbox Code Playgroud)
返回一个对象列表Row,每个对象包含一个 ORM 对象。用户发现这很尴尬,因为他们需要从对象中解压 ORM 对象Row。所以.scalars()现在推荐
results = sess.scalars(query).all()
print(results) # [Payment(id=1), Payment(id=2)]
print(type(results[0])) # <class '__main__.Payment'>
Run Code Online (Sandbox Code Playgroud)
但是,对于返回单个属性(列)的查询,我们不想使用,.scalars()因为这只会为我们提供每行的一列,通常是第一列
query = select(
Payment.id,
Payment.organization_id,
Payment.payment_type,
)
results = sess.scalars(query).all()
print(results) # [1, 2]
Run Code Online (Sandbox Code Playgroud)
相反,我们想使用常规,.execute()这样我们就可以看到所有列
results = sess.execute(query).all()
print(results) # [(1, 123, None), (2, 234, None)]
Run Code Online (Sandbox Code Playgroud)
笔记:
.scalars()在这两种情况下都做同样的事情:返回一个列表,其中包含每行的单个(标量)值(默认值为索引= 0)。
sess.scalars()是首选构造。它只是 的简写sess.execute().scalars()。