Amazon DynamoDB
Update
7 samples, from the least code that works to complete workflows.
What an update does
| Rule | On DynamoDB |
|---|---|
| What is written | Only the attributes present (SET); an attribute set to null is removed (REMOVE): DynamoDB keeps no empty attributes |
| Which item | By its full key: the id (with the key's other attributes, such as an order's customer), or ArxMatch.Columns/ArxMatch.Key naming exactly the key's attributes |
| Other columns | When they give a partition key, of the table or an index: one query finds the items (at most 100), then each is updated by its key, all or nothing, conditioned on still matching (an index can be behind the table). The match columns are never written; RequireSingleRow refuses several (ARX2003) |
| No partition | ARX8001: a write never scans |
| Nothing matched | ARX2002 RecordNotFound: the update is conditional on the item existing, so it never creates one |
| Index keys | When an attribute an index is keyed by changes, give the index key's other attributes too: ARX rewrites the index keys |
| The table's keys | PK, SK, the index key attributes and entity_type are ARX's to write, and can't be matched on (ARX1001) |
| A new key | An entity whose RecordId and id attribute differ is ARX1001, unless new ArxDynamoWriteOptions { AllowKeyChange = true }: the item is read, changed, put under its new key (ARX3001 if taken) and the old one deleted, in one transaction |
| Concurrency | A version attribute declared in the schema catalog (.Version("product", "row_version")): a create writes 1; an update whose entity carries the version it read is written only if the item still has it (ARX2004 RecordChanged otherwise, nothing written) and adds one. Without the version the update isn't checked: the last writer wins, and the version still goes up |
| Names | Placeholders only (#n0); expression or SQL syntax in a name is ARX1017 |
| Rows by a condition | Update finds rows by equal values: the id, a declared key, or columns you give values for (ArxMatch.Columns). To change every row that meets a condition (amount > 100), pass the values and an ArxFilterExpression to UpdateMultipleAsync(values, filter) (the filter must give a partition key; at most 100 items): one call, all or nothing, from 0.1.0-preview.5 (UpdateMultiple, Basics). Before that version: read the rows with RetrieveMultipleAsync and pass them to UpdateMultipleAsync. |
The samples
Basics
The least code that works.
1Update one recordProgressiveThe smallest update, in three scenarios: by the id Create returned, clearing a value, and an item that isn't there.
How an update finds its item in DynamoDB, in four scenarios: an order by its id and its customer, by its key's attributes, every order a query of the customer's partition finds, and a match no partition answers.
Real cases
What an application does: a small CRM and product catalogue.
1Catch an injection attemptProgressiveA "profile" endpoint whose posted fields become the attributes to change, attacked two ways: an update expression in a field name, and a field that tries to rewrite the item's key; then the same form used honestly.
Two people edit the same product: optimistic concurrency with a version attribute, in four scenarios: a create starts the version at 1, the first save wins, the second is told the item changed, and an update without the version.
Advanced cases
Dependency injection, transactions, batch scopes and setting the service up.
1Update in a batch scopeAdvancedCreates and updates in one batch scope, in two scenarios: committed when the body returns, and nothing written when the body throws.
The service set up from DynamoDB's description of the lead table, in two scenarios: preload at startup, then update by the preloaded key with Strict on.
Renumber an order: a new key for an item, in three scenarios: refused unless asked for, the move, and a move onto a number another order has.