题
我有要检索的ID序列。很简单: 通用标签
有更好的方法吗?
解决方案
您的代码绝对正确。
IN
就像一堆X=Y
和OR
一起加入,并且在当代数据库中非常快。
但是,如果ID列表很长,则可以通过传递返回ID列表的子查询来使查询效率更高。
其他提示
代码完全正确。但是,有人要我在做大IN的两种方法之间进行某种套期保值,而不是对单个ID使用get()。
如果有人真的想避免使用SELECT,那么最好的方法是提前在内存中设置所需的对象。例如,您正在处理大量的元素。将工作分解为多个块,例如,按主键或按日期范围排序整个工作集,然后将本地的该块的所有内容本地加载到缓存中: 通用标签
那是现实世界中的用例。
但是为了说明一些SQLAlchemy API,我们可以创建一个对没有记录的IN进行处理的函数,为存在的记录进行本地获取。就是这样: 通用标签
这是一个示范: 通用标签
如果您使用复合主键,则可以使用tuple_
,如
通用标签
请注意,这在SQLite上不可用(请参见 doc )。
我建议看一下它产生的SQL。您可以只打印str(query)来查看它。
我不知道使用标准SQL的理想方法。
还有另一种方法;如果合理预期所涉及的对象已被加载到会话中;您之前曾在同一笔交易中访问过它们,而是可以执行以下操作: 通用标签
在那些对象已经存在的情况下,这将更快,因为不会有任何查询来检索那些对象;另一方面,如果未加载的对象数量超过一小部分,则它将变得非常慢得多,因为它将导致每个丢失实例的查询,而不是针对所有实例的单个查询对象。
当您在进行上述步骤之前执行joinedload()
查询时,这将很有用,因此可以确保它们已经被加载。通常,默认情况下,您应该使用问题中的解决方案,并且仅当发现您一遍又一遍地查询相同的对象时,才探索该解决方案。