在 SQLAlchemy 中查询属性列表而不是元组
- 2025-03-05 09:15:00
- admin 原创
- 68
问题描述:
我正在查询模型的 ID,并返回元组列表(int,)
而不是 ID 列表。有没有办法直接查询属性?
result = session.query(MyModel.id).all()
我意识到这是可能的
results = [r for (r,) in results]
查询是否可以直接返回该表单,而不必自己处理它?
解决方案 1:
当传入 ORM 检测的描述符(例如列)时,每个结果都是一个命名元组,即使只有一列。您可以在列表推导中使用列名来“展平”列表(您可以删除调用.all()
,迭代也会检索对象):
result = [r.id for r in session.query(MyModel.id)]
或者在循环时利用它是一个元组的事实for
,并将其解包为目标的单元素元组:
result = session.query(MyModel.id)
for id, in result:
# do something with the id
后者也可以用于列表推导:
[id for id, in session.query(MyModel.id)]
您实际上没有任何选项可以强制将行结果仅为单一值id
。
解决方案 2:
奇怪的是,SQLalchemy 没有提供合适的解决方案。在 sqlalchemy 中,如果选择一个成员变量(例如列),那么每个结果都是一个命名元组,正如 @Martijn 所说。我使用 python 的 zip 函数找到了解决方案
ZIP 方法
Zip 官方文档
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)] 返回一个元组列表,其中每个元组包含每个参数序列中的第 i 个元素。返回的列表的长度被截断为最短参数序列的长度。
以你的例子来说
result = session.query(MyModel.id).all()
result = zip(*result)[0]
输出:
[id1, id2, id3...]
它的工作原理是,如果你传递如下列表,它将展平作为参数给出的元组列表
[(key11, key21), (key12,key22)]
Zip 会将此元组列表转换为
[(key11, key12), (key21, key22)]
在您的情况下,您需要 MyModel 的每个元组的初始值,因此您可以从列表中取出第 0 个元组。
链式方法
from itertools import chain
result = session.query(MyModel.id).all() # result [(id1,), (id2,), (id3,)]
result = list(chain(*result))
输出
[id1, id2, id3]
For 循环
result = session.query(MyModel.id).all() # result [(id1,), (id2,), (id3,)]
result = [id for id, in result]
输出
[id1, id2, id3]
解决方案 3:
您Result.scalars()
可以创建一个ScalarResult来接收单个对象而不是 Rows。使用 Core 样式的查询语法,您的示例可能如下所示:
>>> from sqlalchemy import select
>>> from sqlalchemy.orm import sessionmaker
>>> session = sessionmaker(...)
>>> result = session.execute(select(MyModel.id))
>>> result.scalars().all()
[1, 2, 3, ...]
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD