MongoEngine/mongoengine

Calling len() on QuerySet during iteration will end iteration prematurely

geowtf opened this issue · 1 comments

Calling len() on a QuerySet object will fetch and cache all results from the database, returning the length of the cached results. If len() is called during iteration, it will cause the iteration to end prematurely. An example:

function test_len(run_len):
    # A collection with enough documents that the cursor will perform multiple db fetches (N > 100).
    docs = SomeDocument.objects()
    run_len = False
    i = 0
    for doc in docs:
        i = i + 1
        _ = run_len and len(docs)  # This causes the issue.

    assert i == docs.count(), i  # When run_len is True, i == 100 < docs.count().

test_len(False)  # Works as expected.
test_len(True)   # Demonstrates issue.

This issue was introduced in commit 9251ce3 while resolving issue #247.

The code you provided runs fine on latest version and the same goes for a simpler version below

users = User.objects()    # has 500 records
for idx, us in enumerate(users):
    if idx == 150:
        print(len(users))
    print(idx)

Re-open with another reproducible code snippet if you still face the issue