以下两种获取结果列表的方法之间是否存在显着差异(性能或其他方面)?
users: Sequence[User] = session.execute(select(User)).scalars().all()
users: Sequence[User] = list(session.execute(select(User)).scalars())
第二个对我来说似乎更Pythonic,并且是可能的,因为
ScalarResult
可以对其行进行迭代,因此调用 list(...scalars())
只是迭代 ScalarResult
对象。但是,由于 .all()
也存在,我认为一定有某种原因,所以也许使用 .all()
更有效?
两者之间有什么区别?如果有的话,幕后原因是什么导致了这种差异?
通过查看源码,似乎还是有区别的。调用
ScalarResult.all()
,它最终会调用 ResultInternal._allrows()
。同时 ScalarResult.__iter__()
(list()
是内部调用)它最终会调用 ResultInternal._iterator_getter()
。
虽然这些方法乍一看似乎有很多重复,但有一个关键区别:
.all()
一次性获取结果,而.__iter__()
逐一流式传输结果。
迭代器方法在您可能需要短路并且知道不需要完整结果集的时候非常有用。但这个例子有点浪费了。
就性能而言,中间有很多层,因此很难评论。但就使用 SQLAlchemy 而言,我认为
.all()
更适合此用例。