Scan whole table and count items in DynamoDB!
1 min read

Scan whole table and count items in DynamoDB!

A tiny snippet I find handy when I need to scan the whole database. Utilises the .LastEvaluatedKey from the return that DynamoDB gives us to query the whole table! Definitely a smart idea, right? It is mostly used for parent data getting on imports, so chill down we are not using it too often or on huge tables for that matter! It also contains some of the other scaffolds we are using (notice the DAO and Domain references on the code).

  async getAllSomethings (): Promise<Something[]> {
    let returnable: Something[] = [];
    const params: ScanInput = {
      TableName: this.tableName,
    };
    let dbRes = { LastEvaluatedKey: 'start' }; // Just here to trigger the initial go
    do {
      dbRes = await this.client.scan(params).promise();
      const items = dbRes.Items as ISomethingDAO[];
      returnable = returnable.concat(items.map(this.mapper.toDomain));
      params.ExclusiveStartKey = dbRes.LastEvaluatedKey;
    } while (typeof dbRes.LastEvaluatedKey !== 'undefined');

    return returnable;
  }

I find it weird how hard dynamoDB makes getting the count of the objects using the CLI instead of a proper client:

aws dynamodb describe-table --table-name my-super-secret-table

It will respond with a JSON. The JSON even contains an ItemCount value, but you are right thinking it couldn't have been that obvious!

{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "suchIndex",
                "AttributeType": "S"
            }
        ],
        "TableName": "my-super-secret-table",
        "KeySchema": [
            {
                "AttributeName": "suchIndex",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2021-08-08T15:12:23.499000+02:00",
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:eu-central-1:xxx:table/my-super-secret-table",
        "TableId": "much-wow",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST",
            "LastUpdateToPayPerRequestDateTime": "2021-08-08T15:12:23.499000+02:00"
        }
    }
}
ItemCount - The number of items in the global secondary index. DynamoDB updates this value approximately every six hours. Recent changes might not be reflected in this value.
after here

It takes the eventual consistency to a whole new level don't you think? What you are left to do is a proper query either using the CLI or code.

aws dynamodb scan --table-name my-super-secret-table --select "COUNT"
// would respond with
{"Count": 1304,"ScannedCount": 1304,"ConsumedCapacity": null}