SQLAlchemy - только один результат возвращается, когда count () говорит, что есть больше - PullRequest
3 голосов
/ 04 августа 2011

У меня проблемы с действительно большим набором результатов, возвращающим только одну строку.

Session.query(TestSet).join(Instance).count()
>> 4283878
Session.query(TestSet).join(Instance).offset(0).limit(100).count()
>> 100
Session.query(TestSet).join(Instance).offset(0).limit(100).all()
>> [<model.testset.TestSet object at 0x043EC2F0>]

То есть all возвращает только один экземпляр моей модели вместо 100. Теперь для чего-то еще более странного:

len(Session.query(TestSet).join(Instance).offset(0).limit(100).distinct().all())
>> 100

Так что, если я добавлю distinct до all, я вернусь ко всем 100 результатам. Что здесь происходит?

1 Ответ

13 голосов
/ 04 августа 2011

Объект Query, когда его просят выполнить итерацию по результатам, представляющим сущность, подобную TestSet, выполняет uniquing на строках результатов на основе идентичности объекта, так что если запрос должен вернуть 100 строк, каждая с одинаковым TestSet первичный ключ, вы получите только один объект результата назад.Это поведение происходит от функции «нетерпеливого соединения» Query, где часто бывает так, что многие строки результатов получают по одной и той же первичной идентичности, но также содержат различную вторичную идентичность связанной строки, которая должна бытьзаполняется в коллекцию по каждому первичному идентификатору - в этом очень распространенном случае желателен только один экземпляр первичного идентификатора.

Давайте затем рассмотрим, что делает distinct().Предположим, что ваш запрос для объектов 4M возвращает 1000 строк с id = 1, 1000 строк с id = 2 и т. Д. Запрос с limit (100) попадает в первые 100 строк с id = 1, Query uniquizes, и вы получаете один результатВозвратите объект, поскольку все они имеют id = 1.Но с distinct() неожиданно мы получаем 100 строк с разными идентичностями, то есть «id = 1», «id = 2», «id = 3».Query затем назначает каждую из этих строк новому TestSet объекту в карте идентификации, и вы получаете 100 строк назад.

Установка echo='debug' на вашем Engine временно покажет отправляемый SQLа также возвращаемые строки результатов.Когда вы видите много строк результатов с одним и тем же первичным ключом, вы знаете, что Query при запросе на возврат полных сущностей будет уникальным для всех этих избыточных идентификаторов вплоть до одного объекта, представленного для каждой строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...