diff --git a/content/design-patterns/ex11partiql/Step1.en.md b/content/design-patterns/ex11partiql/Step1.en.md new file mode 100644 index 00000000..31741476 --- /dev/null +++ b/content/design-patterns/ex11partiql/Step1.en.md @@ -0,0 +1,41 @@ ++++ +title = "Step 1 - Create and load the the Gamers table" +date = 2019-12-02T12:24:33-08:00 +weight = 1 ++++ + + +Run the AWS CLI command to create the table named `Gamers` and create a GSI named `GSI_1` which is partitioned on `SK` attribute of the parent table: + +```bash +aws dynamodb create-table --table-name Gamers \ +--attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S \ +--key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE \ +--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ +--tags Key=workshop-design-patterns,Value=targeted-for-cleanup \ +--global-secondary-indexes "IndexName=GSI_1,\ +KeySchema=[{AttributeName=SK,KeyType=HASH},{AttributeName=PK,KeyType=RANGE}],\ +Projection={ProjectionType=KEYS_ONLY},\ +ProvisionedThroughput={ReadCapacityUnits=5,WriteCapacityUnits=5}" +``` +Wait until the table becomes active: +```bash +aws dynamodb wait table-exists --table-name Gamers +``` + +Navigate to the DynamoDB section of the AWS management console. +In the left navigation pane, choose PartiQL editor. If you cannot see PartiQL, then you need to switch to new DynamoDB console. + +![Amazon DynamoDB PartiQL editor](/images/awsconsolepartiQL.png) + +Using PartiQL editor, run following insert statements to load items in `Gamers` table + +`insert into Gamers value {'PK' : 'Hammer57','SK' : 'Assets','Coins': 1000}` + +`insert into Gamers value {'PK' : 'Hammer57','SK' : 'Bank','Level': 87, 'Points' : 4050 , 'Tier' : 'Elite'}` + +`insert into Gamers value {'PK' : 'Hammer57','SK' : 'Status','Health':'90%', 'Progress' : 30}` + +`insert into Gamers value {'PK' : 'Hammer57','SK' : 'Weapon','Class' : 'Taser', 'Damage' : '55-67', 'Range' : 120}` + +Next, write insert statement for a new gamer - Atom12 with 600 Coins and a second record for Atom12 with Health as 60%, Progress as 70? diff --git a/content/design-patterns/ex11partiql/Step2.en.md b/content/design-patterns/ex11partiql/Step2.en.md new file mode 100644 index 00000000..82417a60 --- /dev/null +++ b/content/design-patterns/ex11partiql/Step2.en.md @@ -0,0 +1,36 @@ ++++ +title = "Step 2 - Create and load the the Gamers table" +date = 2019-12-02T12:24:33-08:00 +weight = 1 ++++ + +Insert statement for loading data for second Gamer - Atom12 + +`insert into Gamers value {'PK' : 'Atom12','SK' : 'Assets','Coins': 600}` + +`insert into Gamers value {'PK' : 'Atom12','SK' : 'Status','Health':'60%', 'Progress' : 70}` + +Use below UPDATE statement to modify `Health` for an item. Where condition in `update` must resolve to a single primary key value. + +`update Gamers +set Health = '100%' +where PK='Hammer57' and SK='Status' +` + +What happens if the WHERE clause of the UPDATE statement does not evaluate to true? Give it a try by changing above update with `PK = 'Hammer58' and SK='Status'` + +Let's decrement coins by 400 for bumping up health to 100%. We will use subtract operator `-`. + +`update Gamers +set Coins=Coins - 400 +where PK='Hammer57' and SK='Assets' +` + +We can view the changes in Coins and Health using `select` statement. + +`select * from Gamers where PK='Hammer57'` + +In real word scenario, above 2 updates should happen simultaneously. Both should either succeed or fail. This can be done using Transactions. Also, we can add a `ConditionCheck` to check if Gamer has enough Coins to buy health. + + +We will see in next section how to use transactions with PartiQL for DynamoDB. diff --git a/content/design-patterns/ex11partiql/Step3.en.md b/content/design-patterns/ex11partiql/Step3.en.md new file mode 100644 index 00000000..c957e3ab --- /dev/null +++ b/content/design-patterns/ex11partiql/Step3.en.md @@ -0,0 +1,35 @@ ++++ +title = "Step 3 - Performing Transactions with PartiQL for DynamoDB" +date = 2019-12-02T12:24:33-08:00 +weight = 1 ++++ + +### Performing Transactions with PartiQL for DynamoDB + +Transactions in DynamoDB can be used to make coordinated, all-or-nothing changes to multiple items both within and across tables. + +You can group multiple Insert, Update, and Delete statements as part of Transaction. But the transaction must consist of either read statements or write statements; you cannot mix both in one transaction. + +We will use transaction to bump up Health and decrement Coins for Gamer - `Atom12` as all or nothing operation. Also, we will add `conditioncheck` to check if Gamer has enough coins. + +We have written following transaction block to meet this requirement. + +``` +[ + { + "Statement": "update Gamers set Health = '100%' where PK='Atom12' and SK='Status'" + }, + { + "Statement": "update Gamers set Coins=Coins - 400 where PK='Atom12' and SK='Assets' and Coins > 400" + } +] +``` +Now, execute this statement. + +`aws dynamodb execute-transaction --transact-statements file://partiql_transactions.json` + +We can view the changes in Coins and Health attributes using `select` statement. Let's run below `select` statement. This time from CLI instead of PartiQL editor. + +`aws dynamodb execute-statement --statement "select * from Gamers where PK='Atom12'"` + +Try running `execute-transaction` statement again. Conditioncheck should fail as number of Coins for this item is now less than 400. diff --git a/content/design-patterns/ex11partiql/Step4.en.md b/content/design-patterns/ex11partiql/Step4.en.md new file mode 100644 index 00000000..07b90a66 --- /dev/null +++ b/content/design-patterns/ex11partiql/Step4.en.md @@ -0,0 +1,46 @@ ++++ +title = "Step 4 - Running Batch Operations with PartiQL for DynamoDB" +date = 2019-12-02T12:24:33-08:00 +weight = 1 ++++ + +### Running Batch Operations with PartiQL for DynamoDB + +This section shows how to perform batch writes on data stored in DynamoDB, using PartiQL. + +In batch operation, entire operation must consist of either read statements or write statements; you cannot mix both in one batch. + +We will add data for new Gamer - `Saber9` as part of a Batch operation. + +The individual insert specified in Batch are atomic; however entire batch operation as a whole is not. We will see this in action by introducing an error in one of the insert statement as part of a batch. + +Below is the batch statement. Notice in last insert statement Sort key is empty. Partition key and sort key attributes of base tables require to be non-empty values. So last insert statement in this batch will fail but others will succeed. + +``` +[ + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':'Assets','Coins':2000}" + }, + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':'Bank','Level':98,'Points':6000,'Tier':'Elite'}" + }, + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':'Games','Genre':{'Action':['Halo','Call Of Duty'], 'Sports':['NBA','NHL']}}" + }, + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':''}" + } +] +``` + +Let's execute below statement. + +`aws dynamodb batch-execute-statement --statements file://partiql_batch.json` + +The response will show success for 3 insert statement and last failed with ValidationError. This is expected as Sort key is empty. + +In `select` statement, we can also get members of map data type. `Genre` is a map attribute in Gamers table. Run following command in PartiQL editor to select `Sports` from Genre attribute. + +`select PK, SK, Genre.Sports from Gamers where PK='Saber9'` + +This concludes Amazon DynamoDB PartiQL module. diff --git a/content/design-patterns/ex11partiql/_index.en.md b/content/design-patterns/ex11partiql/_index.en.md new file mode 100644 index 00000000..474bb5bb --- /dev/null +++ b/content/design-patterns/ex11partiql/_index.en.md @@ -0,0 +1,26 @@ ++++ +title = "Amazon DynamoDB PartiQL" +date = 2019-12-02T10:18:15-08:00 +weight = 9 +chapter = true +pre = "Exercise 8: " +description = "Learn how to use PartiQL in Amazon DynamoDB." ++++ + +Amazon DynamoDB supports PartiQL, a SQL-compatible query language, to select, insert, update, and delete data in Amazon DynamoDB. + +This section shows how to use PartiQL for DynamoDB from the Amazon DynamoDB console, and the AWS Command Line Interface (AWS CLI). + +Following statements are supported in PartiQL for DynamoDB: + +- Select + +- Update + +- Insert + +- Delete + +Transactions and Batch Operations are also supported. + +This example uses an `Gamers` table to demonstrate PartiQL. You will run data manipulation statements - insert, update, delete using PartiQL, use Transactions and conclude with batch operation. diff --git a/design-patterns/cloudformation/lab.yaml b/design-patterns/cloudformation/lab.yaml index d4a01825..1e9cd564 100644 --- a/design-patterns/cloudformation/lab.yaml +++ b/design-patterns/cloudformation/lab.yaml @@ -165,6 +165,10 @@ Resources: - dynamodb:BatchGetItem - dynamodb:UpdateItem - dynamodb:TagResource + - dynamodb:PartiQLInsert + - dynamodb:PartiQLUpdate + - dynamodb:PartiQLDelete + - dynamodb:PartiQLSelect - iam:GetRole - iam:PassRole - lambda:CreateFunction diff --git a/design-patterns/partiql_batch.json b/design-patterns/partiql_batch.json new file mode 100644 index 00000000..0daddc1d --- /dev/null +++ b/design-patterns/partiql_batch.json @@ -0,0 +1,14 @@ +[ + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':'Assets','Coins':2000}" + }, + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':'Bank','Level':98,'Points':6000,'Tier':'Elite'}" + }, + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':'Games','Genre':{'Action':['Halo','Call Of Duty'], 'Sports':['NBA','NHL']}}" + }, + { + "Statement": "INSERT INTO Gamers value {'PK':'Saber9','SK':''}" + } +] diff --git a/design-patterns/partiql_transactions.json b/design-patterns/partiql_transactions.json new file mode 100644 index 00000000..03c729a1 --- /dev/null +++ b/design-patterns/partiql_transactions.json @@ -0,0 +1,8 @@ +[ + { + "Statement": "update Gamers set Health = '100%' where PK='Atom12' and SK='Status'" + }, + { + "Statement": "update Gamers set Coins=Coins - 400 where PK='Atom12' and SK='Assets' and Coins > 400" + } +] diff --git a/static/images/awsconsolepartiQL.png b/static/images/awsconsolepartiQL.png new file mode 100644 index 00000000..bd6a8bd2 Binary files /dev/null and b/static/images/awsconsolepartiQL.png differ