Introduction to Amazon DynamoDB 4: Basic Operation of the Project (CRUD)

Keywords: Database JSON SQL Python Attribute

In the previous section, we introduced the operation of DynamoDB tables. This section describes the addition, modification, acquisition and deletion of items.

Create project

Amazon DynamoDB provides PutItem and BatchWriteItem to write data in two ways

Add a single project

In Amazon DynamoDB, add items to the table using the PutItem operation:

{
    TableName: "Music",
    Item: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today",
        "AlbumTitle":"Somewhat Famous",
        "Year": 2015,
        "Price": 2.14,
        "Genre": "Country",
        "Tags": {
            "Composers": [
                  "Smith",
                  "Jones",
                  "Davis"
            ],
            "LengthInSeconds": 214
        }
    }
}

The primary keys of this table contain Artist and SongTitle. You must specify values for these properties.
The following are some key points to learn about this PutItem example:

  • DynamoDB uses JSON to provide native support for documents. This makes DynamoDB very suitable for storing semi-structured data, such as Tags. You can also retrieve and manipulate data from JSON documents. A kind of

  • Except for primary keys (Artist and SongTitle), Music tables have no predefined properties. A kind of

  • Most SQL databases are transaction-oriented. When you issue an INSERT statement, the data modification is not permanent until you issue a COMMIT statement. With Amazon DynamoDB, the effect of PutItem operation is permanent when DynamoDB replies through HTTP 200 status code (OK). A kind of

Python Example

boto3

# ...
table = db3.Table('Music')
table.put_item(
      Item = {
        "Artist": "No One You Know",
        "SongTitle": "My Dog Spot",
        "AlbumTitle": "Hey Now",
        "Price": Decimal('1.98'),
        "Genre": "Country",
        "CriticRating": Decimal('8.4')
    }
)

Out[98]:
{'ResponseMetadata': {'HTTPHeaders': {'content-length': '2',
   'content-type': 'application/x-amz-json-1.0',
   'server': 'Jetty(8.1.12.v20130726)',
   'x-amz-crc32': '2745614147',
   'x-amzn-requestid': 'c7c6be12-9752-403f-97b1-a9ac451a0a98'},
  'HTTPStatusCode': 200,
  'RequestId': 'c7c6be12-9752-403f-97b1-a9ac451a0a98',
  'RetryAttempts': 0}}
  
table.put_item(
      Item = {
        "Artist": "No One You Know",
        "SongTitle": "Somewhere Down The Road",
        "AlbumTitle":"Somewhat Famous",
        "Genre": "Country",
        "CriticRating": Decimal('8.4'),
        "Year": 1984
    }
)
table.put_item(
      Item = {
        "Artist": "The Acme Band",
        "SongTitle": "Still In Love",
        "AlbumTitle":"The Buck Starts Here",
        "Price": Decimal('2.47'),
        "Genre": "Rock",
        "PromotionInfo": {
            "RadioStationsPlaying":[
                 "KHCR", "KBQX", "WTNR", "WJJH"
            ],
            "TourDates": {
                "Seattle": "20150625",
                "Cleveland": "20150630"
            },
            "Rotation": "Heavy"
        }
    }
)

table.put_item(
      Item = {
        "Artist": "The Acme Band",
        "SongTitle": "Look Out, World",
        "AlbumTitle":"The Buck Starts Here",
        "Price": Decimal('0.99'),
        "Genre": "Rock"
    }
)

Note

  • PutItem is an override operation. If the primary key is the same, the second execution will override the previous data.

  • In addition to PutItem, Amazon DynamoDB also supports writing BatchWriteItem operations to multiple (up to 25) projects simultaneously.

Adding multiple projects

Python Example

boto3

# ...
table = db3.Table('Music')

with table.batch_writer() as batch:
    batch.put_item(
        Item = {
            "Artist": "The Acme Band",
            "SongTitle": "Look Out, World",
            "AlbumTitle":"The Buck Starts Here",
            "Price": Decimal('0.99'),
            "Genre": "Rock"
        }
    )
    batch.put_item(
        Item = {
            "Artist": "The Acme Band 0",
            "SongTitle": "Look Out, World",
            "AlbumTitle":"The Buck Starts Here",
            "Price": Decimal('1.99'),
            "Genre": "Rock"
        }
    )
    batch.put_item(
        Item = {
            "Artist": "The Acme Band 1",
            "SongTitle": "Look Out, World",
            "AlbumTitle":"The Buck Starts Here",
            "Price": Decimal('2.99'),
            "Genre": "Rock"
        }
    )
    batch.put_item(
        Item = {
            "Artist": "The Acme Band 1",
            "SongTitle": "Look Out, World",
            "AlbumTitle":"The Buck Starts Here",
        }
    )

BatchWriteItem uses the overwrite_by_pkeys=['partition_key','sort_key'] parameter to remove duplicate parts of the project.

with table.batch_writer(overwrite_by_pkeys=['partition_key', 'sort_key']) as batch:
    batch.put_item(
        Item={
            'partition_key': 'p1',
            'sort_key': 's1',
            'other': '111',
        }
    )
    batch.put_item(
        Item={
            'partition_key': 'p1',
            'sort_key': 's1',
            'other': '222',
        }
    )

After weight removal, it is equivalent to:

with table.batch_writer(overwrite_by_pkeys=['partition_key', 'sort_key']) as batch:
    batch.put_item(
        Item={
            'partition_key': 'p1',
            'sort_key': 's1',
            'other': '222',
        }
    )

Read data

With SQL, we can use SELECT statements to retrieve one or more rows from a table. You can use the WHERE clause to determine the data returned to you

DynamoDB provides the following operations to read data:

  • GetItem - Retrieves a single item from a table. This is the most efficient way to read a single project because it provides direct access to the physical location of the project. (DynamoDB also provides BatchGetItem operations, which perform up to 100 GetItem calls in a single operation.)

  • Query - Retrieves all items with a specific partition key. In these projects, you can apply conditions to sort keys and retrieve only part of the data. Query provides fast and efficient access to partitions that store data.

  • Scan - Retrieves all items in the specified table.

    Note

With relational databases, you can use SELECT statements to join data in multiple tables and return results. Connections are the basis of relational models. To ensure efficient connection execution, the performance of databases and their applications should be continuously optimized.
DynamoDB is a non-relational NoSQL database and does not support table joins. Instead, the application reads data from one table at a time.

Read the project using the primary key of the project

DynamoDB provides GetItem operations to retrieve items by their primary keys.

By default, GetItem returns the entire project and all its properties.

{
    TableName: "Music",
    Key: {
        "Artist": "No One You Know",
        "SongTitle": "Call Me Today"
    }
}

You can add the Project Expression parameter to return only some properties:

{
    TableName: "Music",
    Key: {
        "Artist": "No One You Know",
        "SongTitle": "Call Me Today"
    },
    "ProjectionExpression": "AlbumTitle, Price"
}
  • DynamoDB GetItem operation is very efficient: this operation uses the primary key value to determine the exact storage location of the related item and retrieves the item directly from this location.

  • SQL SELECT statements support multiple queries and table scans. DynamoDB provides similar functionality through its Query and Scan operations, as described in query and scan tables.

  • The SQL SELECT statement executes table join, which allows you to retrieve data from multiple tables at the same time. DynamoDB is a non-relational database. Therefore, it does not support table joins.

Query and Scan operations are described in detail in subsequent chapters.

Python Example

boto3

# ...
table = db3.Table('Music')
response = table.get_item(
    Key={
        "Artist": "The Acme Band",
        "SongTitle": "Still In Love"
    }
)
item = response['Item']
print(item)

# output
{
        "Artist": "The Acme Band",
        "SongTitle": "Still In Love",
        "AlbumTitle":"The Buck Starts Here",
        "Price": Decimal('2.47'),
        "Genre": "Rock",
        "PromotionInfo": {
            "RadioStationsPlaying":[
                 "KHCR", "KBQX", "WTNR", "WJJH"
            ],
            "TourDates": {
                "Seattle": "20150625",
                "Cleveland": "20150630"
            },
            "Rotation": "Heavy"
        }
    }
    
response = table.get_item(
    Key={
        "Artist": "The Acme Band",
        "SongTitle": "Still In Love"
    },
    ProjectionExpression = "AlbumTitle, Price"
)
item = response['Item']
print(item)
{
    'AlbumTitle': u'The Buck Starts Here',
    'Price': Decimal('2.47')
} 

To update

The SQL language provides UPDATE statements for modifying data. DynamoDB uses the Update Item operation to accomplish similar tasks.

In DynamoDB, you can modify a single project using the Update Item operation. (If you want to modify multiple projects, you must use multiple Update Item operations.)
Examples are as follows:

{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET RecordLabel = :label",
    ExpressionAttributeValues: { 
        ":label": "Global Records"
    }
}
  • You must specify the Key attribute of the project to be modified and an Update Expression for specifying the attribute value.

  • Update Item replaces the entire project rather than a single attribute.

  • The behavior of Update Item is similar to that of the "upsert" operation: if the item is in a table, update the item, or add (insert) a new item.

  • UpdateItem supports conditional writing, in which case the operation is successfully completed only when the calculated result of a particular ConditionExpression is true

{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET RecordLabel = :label",
    ConditionExpression: "Price >= :p",
    ExpressionAttributeValues: { 
        ":label": "Global Records",
        ":p": 2.00
    }
}
  • Update Item also supports atomic counters or attributes of type Number (incremental or decreasing).

Following is an example of an Update Item operation that initializes a new property (Plays) to track the number of times a song has been played:

{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET Plays = :val",
    ExpressionAttributeValues: { 
        ":val": 0
    },
    ReturnValues: "UPDATED_NEW"
}

The Return Values parameter is set to UPDATED_NEW, which returns the new value of any updated attribute. In this example, it returns 0 (zero).

When someone plays this song, use the following Update Item operation to increase Plays by 1:

{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET Plays = Plays + :incr",
    ExpressionAttributeValues: { 
        ":incr": 1
    },
    ReturnValues: "UPDATED_NEW"
}

Python Example

boto3
Modify a single project using the Update Item operation

import boto3
import json
import decimal

class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            if o % 1 > 0:
                return float(o)
            else:
                return int(o)
        return super(DecimalEncoder, self).default(o)

db3 = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000")

table = db3.Table('Music')

response = table.update_item(
    Key={
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression="SET RecordLabel = :label",
    ExpressionAttributeValues={
        ":label": "Global Records"
    },
    ReturnValues="UPDATED_NEW"
)

print(json.dumps(response, indent=4, cls=DecimalEncoder))

Update Item condition write price greater than or equal to 2.00 Update Item execution update

table = db3.Table('Music')

response = table.update_item(
    Key={
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression="SET RecordLabel = :label",
    ConditionExpression="Price >= :p",
    ExpressionAttributeValues={
        ":label": "Global Records",
        ":p": 2.00
    },
    ReturnValues="UPDATED_NEW"
)

An example of the Update Item operation that initializes a new property (Plays) to track the number of times a song has been played

table = db3.Table('Music')

response = table.update_item(
    Key={
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression="SET Plays = :val",
    ExpressionAttributeValues={ 
        ":val": 0
    },
    ReturnValues="UPDATED_NEW"
)

Use the Update Item operation to increase Plays by 1

table = db3.Table('Music')

response = table.update_item(
    Key={
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression="SET Plays = Plays + :incr",
    ExpressionAttributeValues={ 
        ":incr": 1
    },
    ReturnValues="UPDATED_NEW"
)

delete item

In SQL, the DELETE statement Deletes one or more rows from the table. DynamoDB deletes an item at a time using the DeleteItem operation.

In DynamoDB, you can use the DeleteItem operation to delete data (one item at a time) from a table. You must specify the primary key value of the project. Examples are as follows:

{
    TableName: "Music",
    Key: {
        Artist: "The Acme Band", 
        SongTitle: "Look Out, World"
    }
}

Note

In addition to DeleteItem, Amazon DynamoDB also supports BatchWriteItem operations that delete multiple items simultaneously.

DeleteItem supports conditional writing, in which case the operation is successfully completed only when the calculated result of a particular ConditionExpression is true. For example, the following DeleteItem operation deletes items only if they have a RecordLabel attribute:

{
    TableName: "Music",
    Key: {
        Artist: "The Acme Band", 
        SongTitle: "Look Out, World"
    },
   ConditionExpression: "attribute_exists(RecordLabel)"
}

Python Example

boto3

table = db3.Table('Music')
table.delete_item(
    Key={
        'AlbumTitle': 'Hey Now'
        'Artist': 'No One You Know'
    }
)

In this section, we introduce the basic operation of the project (CRUD), and in the next section, we will introduce the creation and management of the index.

Posted by njm on Sun, 07 Apr 2019 16:27:30 -0700