DynamoDB and its Data Pane Operations - 3
Tags: dynamodb, cli, aws
Published: 2022-12-28 22:26:53

This is the 3rd and the last article in the series for **[Data Pane 1 (read-write) operations](https://dev.to/aws-builders/dynamodb-and-its-data-pane-operations-1-2772)** and **[Data Pane 2 (read-write) operations](https://dev.to/aws-builders/dynamodb-and-its-data-pane-operations-2-4maa)**.

In this article, I am going to show you such operations on DynamoDB **`scan`**. Some of the criteria which can be used in the scan operations are - **`Filter Expression`**, with options, such as **`max items`**, **`--starting-token`**, **`Count`** and **`ScannedCount`** and **`Reserved words`**.


In this article, I am **`not`** explaining the terminology and the concepts used in DynamoDB Tables. Please visit my previous articles for this - **[DynamoDB and its Control Pane Operations - 1](https://dev.to/aws-builders/dynamodb-and-its-control-pane-operations-1-36bk)** and **[DynamoDB and its Control Pane Operations - 2](https://dev.to/aws-builders/dynamodb-and-its-control-pane-operations-2-327b)**.

Since the scan operation involves scanning the whole table and not just a single item, there is no **`Key condition expression`**.

## Scan

- Retrieves all items in the specified table or index. 

- You can retrieve entire items, or just a subset of their attributes. 


##  Filter Expression 

- It removes some items from the Result Set returned by the Query.

- This can be compared in SQL to **`this is the part of the WHERE clause that acts on the non-Key attributes`**.

## Max items

- If we want to limit the number of items then we use the **`--max-items`** option. 

## ScannedCount and Count

- Counts the items in the results

- If you don't use a filter expression, ScannedCount and Count have the same value.


_**Let’s get started!**_

Please visit my **[GitHub Repository for DynamoDB articles](https://github.com/awsmine/DynamoDB_projects)** on various topics being updated on constant basis.



# Pre-requisites:
- AWS user account with admin access, not a root account.
- Cloud9 IDE with AWS CLI.

# Objectives:

**1.** Create a DynamoDB table 

**2.** Add 3 items to the table

**3.** Scan the table to get a subset of the attributes

**4.** Scan the table to limit the items number to 1 using **`--max-items`** parameter.

**5.** Issue the scan request again, this time passing the  NextToken value into the **`--starting-token`** parameter

**6.** Dealing with Reserved words



# Resources Used:

[Amazon DynamoDB Developer Guide](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html)

[scan cli](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/scan.html)

[Reserved words](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html)

# Steps for implementation to this project:

- Copy the and paste the code in your AWS Cloud9 command prompt. 

### 1. Create a DynamoDB table 



```
aws dynamodb create-table \
    --table-name Movies \
    --attribute-definitions \
        AttributeName=Title,AttributeType=S \
        AttributeName=Review,AttributeType=S \
    --key-schema \
        AttributeName=Title,KeyType=HASH \
        AttributeName=Review,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=10,WriteCapacityUnits=5
aws dynamodb wait table-exists --table-name Movies
```



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d3lnr9b92kds3hs105hw.png)


### 2. Add 3 items to the table


```
aws dynamodb put-item \
    --table-name Movies \
    --item '{
           "Title": {"S": "Abhimaan"},
           "Review": {"S": "Excellent"},
           "Actor": {"S": "Big B"},
           "PostedBy": {"S": "User A"},
           "Songs": {"L": [ {"S": "Song1"},
                            {"S": "Song2"}
                          ]
                    }
            }'
aws dynamodb put-item \
    --table-name Movies \
    --item '{
           "Title": {"S": "Abhimaan"},
           "Review": {"S": "Terrific"},
           "Actor": {"S": "Jaya"},
           "PostedBy": {"S": "User B"},
           "Songs": {"L": [ {"S": "Song1"},
                            {"S": "Song2"}
                          ]
                    }
            }'
aws dynamodb put-item \
    --table-name Movies \
    --item '{
           "Title": {"S": "Abhimaan"},
           "Review": {"S": "Too Good"},
           "Actor": {"S": "Bindu"},
           "PostedBy": {"S": "User A"},
           "Songs": {"L": [ {"S": "Song1"},
                            {"S": "Song2"}
                          ]
                    }
            }'  
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/np7g96tnaqy67ocg2d6o.png)

### 3. Scan the table to get a subset of the attributes

- Scan scanned all 3 items (ScannedCount) in the table - 
**`"ScannedCount": 3`**

- But the Filter Expression reduced our result set size down to 2 items (Count) - **`"Count": 2`**

- Hence, you should see 2 items in the result set, as the non-key attribute **`PostedBy`** references 2 items in **`Movies`** table.

- --item '{
            "PostedBy": {"S": "User A"}

- Refer the Movies table to check


```
aws dynamodb scan \
    --table-name Movies \
    --filter-expression 'PostedBy = :user' \
    --expression-attribute-values '{
        ":user" : {"S": "User A"}
    }' \
    --return-consumed-capacity TOTAL
```

### 4. Scan the table to limit the items number to 1 using **`--max-items`** parameter.


```
aws dynamodb scan \
    --table-name Movies \
    --filter-expression 'PostedBy = :user' \
    --expression-attribute-values '{
        ":user" : {"S": "User A"}
    }' \
    --max-items 1 \
    --return-consumed-capacity TOTAL

```

- the scan response will show a **`NextToken`** which we can then issue to a next scan call to pick up the 2nd item.

#### NextToken

```


"NextToken": "eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDF9"


```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/br2xl4raxge88olzag78.png)






### 5. Issue the scan request again, this time passing the  NextToken value into the **`--starting-token`** parameter

```
aws dynamodb scan \
    --table-name Movies \
    --filter-expression 'PostedBy = :user' \
    --expression-attribute-values '{
        ":user" : {"S": "User A"}
    }' \
    --max-items 1 \
    --starting-token eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDF9 \
    --return-consumed-capacity TOTAL
```



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dyxqly3gu8zt2zjs0ia4.png)




### 6. Dealing with Reserved words

- In the Filter Expression, if the attribute name is actually a DynamoDB Reserved Word, it will throw an error - **`An error occurred (ValidationException) when calling the Scan operation: Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Number`**

- Because the **`Number`** attribute name is actually a DynamoDB Reserved Word. 

- This can be solved by putting a placeholder which is a **`# (pound sign)`** in the FilterExpression and provide the actual attribute name in the **`--expression-attribute-names `**

```
aws dynamodb scan \
    --table-name <Table Name> \
    --filter-expression 'Pictures >= :pictures AND #Number >= :comment' \
    --expression-attribute-values '{
        ":pictures" : {"N": "1"},
        ":Number" : {"S": "Nice"}
    }' \
    --expression-attribute-names '{"#Number" : "number"}' \
    --return-consumed-capacity TOTAL
```


# Cleanup

- Delete the table **`Movies`**


# What we have done so far

We have successfully demonstrated Data Pane operations on DynamoDB **`scan`**, using these criteria - **`Filter Expression`**, with options, such as **`max items`**, **`--starting-token`**, **`Count`** and **`ScannedCount`**, **`Reserved words`**.