> For the complete documentation index, see [llms.txt](https://anon-coders-notes.gitbook.io/techwriterdev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://anon-coders-notes.gitbook.io/techwriterdev/cloud/aws/developerassociate/services/20_dynamodb/01_operations.md).

# Operations

## Writing Data

| Operation Name       | Description                                                                                                                                                                                      |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PutItem`            | <p>Create a new item or fully replace an old item <em>(using Primary Key)</em>.<br>It Consumes <code>WCU</code></p>                                                                              |
| `UpdateItem`         | <p>Edits an existing item's attribute or add items if it does not exists.<br>Can be used to implement <code>Atomic Counters</code> - A numeric attribute that's unconditionally incremented.</p> |
| `Conditional Writes` | <p>Accept a write/update/delete only if condition are met, otherwise return an error.<br>Helps with concurrent access to items.</p>                                                              |

### Conditional Writes

* For `PutItem`, `UpdateItem`, `DeleteItem` and `BatchWriteItem` one can specify a condition expression to determine which items should be modified.
* Condition expressions like
  * attribute\_exists
  * attribute\_not\_exists
  * attribute\_type
  * contains(string)
  * begins\_with(string)
  * IN (:cat1, :cat2)
  * size(length)
* `FilterExpression` filters the result of read queries, while `Condition Expressions` for write operations.
* An example query would look as follows,

  ```sh
      aws dynamodb update-item \
          --table-name ProductCatalog \
          --key '{"Id":{"N":"1"}}' \
          --update-expression "SET Price = :newval" \
          --condition-expression "Price > :limit" \
          --expression-attribute-values file://expression-attribute-values.json
  ```
* If `attribute_not_exists(partition_key)` is in condition-expresion it makes sure to not overwrite an item if the item already exists, its a trick to prevent overwrite. Can be combined with sort\_key if that is also part of partition key.
* More about them can be read [here](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.ConditionalUpdate)

## Reading Data

| Operation Name | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GetItem`      | <p>Reads based on primary key to retrieve one item.<br>Primary key can be <strong>HASH</strong> or <strong>HASH + RANGE</strong>.<br>Eventually Consistent Read.<br>Option to use Strongly Consistent Reads <em>(more RCU, hence might take longer)</em>.<br><strong>ProjectedExpression</strong> can be specified to retrieve only certain attributes.</p>                                                                                                                                                                                       |
| `Query`        | <p>Return items based on <code>KeyConditionExpression</code>, partition key value must be required. <code>Sort key</code> is optional.<br><code>FilterExpression</code> is used for additional filtering after Query operation.<br>Used only with non-key attributes. <em>(It does not allow HASH or RANGE attributes)</em>.<br>It returns a list of items specified in <strong>Limit</strong>, or upto 1MB.<br>Pagination on result can be done to get more result.<br>Can query table, a local secondary index or a Global secondary Index.</p> |
| `Scan`         | <p>Scan an entire table and then filter out data, it is inefficient though.<br>Returns upto 1 MB of data, use pagination to keep on reading.<br>Consumes a lot of RCU.<br>Also has option to do <code>Parallel Scan</code>, in which multiple workers will scan multiple data segment at same time and increases throughput and <code>RCU</code> consumed.<br>Ensure to use limit to reduce the impact of parallel scans.<br>Can use <strong>ProjectionExpression</strong> and <strong>FilterExpression</strong>.</p>                             |

## Delete Data

| Operation Name | Description                                      |
| -------------- | ------------------------------------------------ |
| `DeleteItem`   | Delete an individual Item or conditional delete. |
| `DeleteTable`  | Delete an whole table and all its items.         |

## Batch Operations

* Allow to save in latency by reducing the number of API calls.
* Operations are done in parallel for better efficiency.
* Part of batch can fail, in which case would need to try again for failed items.

| Operation Name   | Description                                                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BatchWriteItem` | <p>Supports upto 25 <strong>PutItem</strong> and/or <strong>DeleteItem</strong> in one call.<br>Upto 16 MB of data written, upto 400 KB of data per item.<br><strong>Can't update items </strong><em><strong>(use UpdateItem)</strong></em>.<br><strong>UnprocessedItems</strong> for failed write operations are returned on failure, and to correct the failure use exponential back-off or add <code>WCU</code>.</p> |
| `BatchGetItem`   | <p>Returns items from one or more tables. Upto 100 items and 16 MB of data.<br>Items are retrieved in parallel to minimize latency.<br><strong>UnprocessedKeys</strong> for failed read operations are returned on failure, and to correct the failure use exponential back-off or add <code>RCU</code>.</p>                                                                                                            |

## Some more Operations

1. Table Cleanup
   * Scan and `DeleteItem`
     * Very slow, consumes RCU and WCU and hence expensive
   * Drop Table
     * Fast, cheap and efficient
2. Copying a Table
   * AWS Data Pipeline.
     * This will spin up an EMR *(MapReduce)* cluster.
     * `EMR` cluster will read data from DynamoDB table and write that data to S3.
     * Once above step is done, it will read back the data from S3 and write it to new DynamoDB table.
   * Backup and restore
     * Takes some time.
   * AWS Glue *(ETL Job)*
     * Creates a script and reads from source table and then writes to destination
   * Scan and `PutItem`/`BatchWriteItem`
     * Write your own code and allows to do some transformation on data if needed.

## Optimistic Locking

* If multiple clients tries to operate on same set of data then only of them will succeed. Other clients will receive `Optimistic Locking` exception.
* This ensures that concurrent operation has isolation when acting on same data to avoid data corruption and incorrect result.
* This locking is acheived by maintaining a column in table named `version`. Every update will increment this `version` column. If an update tries to update while possessing incorrect version number then the operation will fail.
* This allows higher concurrency and locking data only at transaction commit time.

## PartiQL

* SQL compatible query language for DynamoDB.
* Allows you to `select`, `insert`, `update` and `delete` data in DynamoDB across multiple DynamoDB Tables.
* Supports batch operations as well.
* **No joins are allowed**.
* Queries can be run from,
  * AWS Management Console
  * NoSQLWorkbench for DynamoDB
  * SDK
  * AWS-CLI
  * DynamoDB APIs
