Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pynamodb last_evaluated_key always return null

I'm using Pynamodb for interacting with dynamodb. However, last_evaluated_key always returns null even if there are multiple items. When I run this query

results = RecruiterProfileModel.profile_index.query(
        hash_key=UserEnum.RECRUITER,
        scan_index_forward=False,
        limit=1,
    )

If I try getting this value

results.last_evaluated_key

it always returns null.

However, if I dump the results object, it returns

{
    "page_iter": {
        "_operation": {},
        "_args": [
            "recruiter"
        ],
        "_kwargs": {
            "range_key_condition": null,
            "filter_condition": null,
            "index_name": "PROFILE_INDEX",
            "exclusive_start_key": {
                "sk": {
                    "S": "PROFILE#6ab0f5bc-7283-4236-9e37-ea746901d19e"
                },
                "user_type": {
                    "S": "recruiter"
                },
                "created_at": {
                    "N": "1677398017.685749"
                },
                "pk": {
                    "S": "RECRUITER#6ab0f5bc-7283-4236-9e37-ea746901d19e"
                }
            },
            "consistent_read": false,
            "scan_index_forward": false,
            "limit": 1,
            "attributes_to_get": null
        },
        "_last_evaluated_key": {
            "sk": {
                "S": "PROFILE#95a4f201-2475-45a7-b096-5167f6a4d639"
            },
            "user_type": {
                "S": "recruiter"
            },
            "created_at": {
                "N": "1677398017.68518"
            },
            "pk": {
                "S": "RECRUITER#95a4f201-2475-45a7-b096-5167f6a4d639"
            }
        },
        "_is_last_page": false,
        "_total_scanned_count": 2,
        "_rate_limiter": null,
        "_settings": {
            "extra_headers": null
        }
    },
    "_map_fn": {},
    "_limit": 0,
    "_total_count": 1,
    "_index": 1,
    "_count": 1,
    "_items": [
        {
            "company_name": {
                "S": "fletcher-rodriguez"
            },
            "created_at": {
                "N": "1677398017.685749"
            },
            "last_name": {
                "S": "craig"
            },
            "first_name": {
                "S": "tyler"
            },
            "designation": {
                "S": "manager"
            },
            "verification_status": {
                "S": "pending"
            },
            "sk": {
                "S": "PROFILE#6ab0f5bc-7283-4236-9e37-ea746901d19e"
            },
            "user_type": {
                "S": "recruiter"
            },
            "email": {
                "S": "[email protected]"
            },
            "pk": {
                "S": "RECRUITER#6ab0f5bc-7283-4236-9e37-ea746901d19e"
            }
        }
    ]
}

You can clearly see that last_evaluated_key exists over there. I'm getting confused here. Please help. I've deadlines to meet. Thank you in advance.

Edit: Here is a video attachment of trying to get the value of last_eveluated_key in different ways and they all return null pynamodb last_evaluated_key issue Gdrive video

like image 225
Koushik Das Avatar asked Dec 07 '25 06:12

Koushik Das


2 Answers

The result returned by the query() is the ResultIterator object, which is an iterator. Its last_evaluated_key is the key of the last item you pulled from the iterator, not DynamoDB. Because your code have not yet asked to retrieve any items, the last_evaluated_key is not set.

You need to process some or all of the items in the result:

for item in results:
    print(item)
return results.last_evaluated_key

then you will get the key of the last item you processed.

like image 75
Alex Chadyuk Avatar answered Dec 09 '25 19:12

Alex Chadyuk


I've never used Pynamo but the key to LastEvaluatedKey looks like _last_evaluated_key which is prefixed with _ have you tried that?

results._last_evaluated_key

Update based on question:

Pagination and last evaluated key

The query returns a ResultIterator object that transparently paginates through results. To stop iterating and allow the caller to continue later on, use the last_evaluated_key property of the iterator:

def iterate_over_page(last_evaluated_key = None):
    results = TestModel.view_index.query('foo', TestModel.view > 0,
                                         limit=10,
                                         last_evaluated_key=last_evaluated_key)
    for item in results:
       ...
    return results.last_evaluated_key

Ref

I believe your issue is that you haven't initiated the query when you're looking for the LastEvaluatedKey. Try print some items first, before trying to obtain the key.

like image 36
Lee Hannigan Avatar answered Dec 09 '25 20:12

Lee Hannigan