Introduction to Amazon DynamoDB 3: Basic operation of tables

Keywords: Database Python AWS JSON

Basic operation of Amazon DynamoDB table

The previous two articles introduced how DynamoDB is installed locally and the basic working principles and API s. This section focuses on how to use DynamoDB.

Basic DynamoDB operations include table operations, project operations, and index management.

The first is to link to the database. Unlike relational databases, DynamoDB is a Web service with stateless interactions. The application does not need to maintain a persistent network connection. Instead, interaction with DynamoDB is done through HTTP(S) requests and responses.

The steps to perform an operation are:

  1. The application sends HTTP(S) requests to DynamoDB. The request contains the name and parameters of the DynamoDB operation to be performed. DynamoDB will execute the request immediately.

  2. DynamoDB returns an HTTP(S) response containing the result of the operation. If an error occurs, DynamoDB returns the HTTP error status and message.

In most cases, we write application code to access DynamoDB. You can also use the AWS management console or AWS Command Line Interface (AWS CLI) to send temporary requests to DynamoDB and view the results.

Let's show the rest in code.

Table operation

We know that relational models need a well-defined architecture in which data will be standardized into tables, columns and rows. In addition, all relationships are defined between tables, columns, indexes, and other database elements. Unlike DynamoDB, DynamoDB has no architecture. Each table must have a primary key that uniquely identifies each data item, but there are no similar constraints on other non-key attributes. DynamoDB can manage structured or semi-structured data, including JSON documents.

Tables are the basic data structures in relational databases and DynamoDB. Relational database management system (RDBMS) requires that the schema of tables be defined when tables are created. In contrast, DynamoDB tables have no architecture - unlike primary keys, we do not need to define any attributes or data types when creating tables.

new table

DynamoDB uses the CreateTable operation to create tables and specify parameters. The request syntax is as follows:

{
   "AttributeDefinitions": [ 
      { 
         "AttributeName": "string",
         "AttributeType": "string"
      }
   ],
   "GlobalSecondaryIndexes": [ 
      { 
         "IndexName": "string",
         "KeySchema": [ 
            { 
               "AttributeName": "string",
               "KeyType": "string"
            }
         ],
         "Projection": { 
            "NonKeyAttributes": [ "string" ],
            "ProjectionType": "string"
         },
         "ProvisionedThroughput": { 
            "ReadCapacityUnits": number,
            "WriteCapacityUnits": number
         }
      }
   ],
   "KeySchema": [ 
      { 
         "AttributeName": "string",
         "KeyType": "string"
      }
   ],
   "LocalSecondaryIndexes": [ 
      { 
         "IndexName": "string",
         "KeySchema": [ 
            { 
               "AttributeName": "string",
               "KeyType": "string"
            }
         ],
         "Projection": { 
            "NonKeyAttributes": [ "string" ],
            "ProjectionType": "string"
         }
      }
   ],
   "ProvisionedThroughput": { 
      "ReadCapacityUnits": number,
      "WriteCapacityUnits": number
   },
   "StreamSpecification": { 
      "StreamEnabled": boolean,
      "StreamViewType": "string"
   },
   "TableName": "string"
}

The following parameters must be provided to CreateTable:

  • TableName - Table name.

  • KeySchema - Attributes for primary keys. For more information, see tables, items, and attributes and primary keys.

  • Attribute Definitions - Data type of key schema attributes.

  • Provisioned Throughput --- The number of reads and writes per second that need to be performed on this table. DynamoDB will retain sufficient storage and system resources to always meet throughput requirements. These settings can also be changed after creation using the Update Table operation. Storage allocation is entirely managed by DynamoDB, and we do not need to specify storage requirements for tables.

In the definition of AttributeType:

  • S - String Type

  • N - Number Type

  • B-binary type

Python Example

boto3

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


table = db3.create_table(
    TableName='Music',
    KeySchema=[
        { 
            'AttributeName': "Artist", 
            'KeyType': "HASH"
        },
        { 
            'AttributeName': "SongTitle", 
            'KeyType': "RANGE"
        }
    ],
    AttributeDefinitions=[
        { 
            'AttributeName': "Artist", 
            'AttributeType': "S" 
        },
        { 
            'AttributeName': "SongTitle", 
            'AttributeType': "S" 
        }
    ],
    ProvisionedThroughput={       
        'ReadCapacityUnits': 1, 
        'WriteCapacityUnits': 1
    }
)


# Wait until the table exists.
table.meta.client.get_waiter('table_exists').wait(TableName='Music')

# Print out some data about the table.
print(table.item_count)

The primary keys of this table include Artist (partition key) and SongTitle (sort key).

Get information about tables

After the table is built, we can use the Describe Table command to view the information of the table.
The only parameter is the table name, as follows:

{
    TableName : "Music"
}

The response from DescribeTable is as follows:

{
  "Table": {
    "AttributeDefinitions": [
      {
        "AttributeName": "Artist",
        "AttributeType": "S"
      },
      {
        "AttributeName": "SongTitle",
        "AttributeType": "S"
      }
    ],
    "TableName": "Music",
    "KeySchema": [
      {
        "AttributeName": "Artist",
        "KeyType": "HASH"  //Partition key
      },
      {
        "AttributeName": "SongTitle",
        "KeyType": "RANGE"  //Sort key
      }
    ],

    ...remaining output omitted...

Describe Table also returns information about indexes in tables, pre-configured throughput settings, approximate number of items, and other metadata.

Python Example

boto3

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

db3.meta.client.describe_table(TableName='Music')
# The results are as follows

{'ResponseMetadata': {'HTTPHeaders': {'content-length': '569',
   'content-type': 'application/x-amz-json-1.0',
   'server': 'Jetty(8.1.12.v20130726)',
   'x-amz-crc32': '2801025854',
   'x-amzn-requestid': '2dafeeab-8d79-4b32-ad1f-03983624ab41'},
  'HTTPStatusCode': 200,
  'RequestId': '2dafeeab-8d79-4b32-ad1f-03983624ab41',
  'RetryAttempts': 0},
 u'Table': {u'AttributeDefinitions': [{u'AttributeName': u'Artist',
    u'AttributeType': u'S'},
   {u'AttributeName': u'SongTitle', u'AttributeType': u'S'}],
  u'CreationDateTime': datetime.datetime(2016, 12, 28, 11, 25, 12, 657000, tzinfo=tzlocal()),
  u'ItemCount': 0,
  u'KeySchema': [{u'AttributeName': u'Artist', u'KeyType': u'HASH'},
   {u'AttributeName': u'SongTitle', u'KeyType': u'RANGE'}],
  u'ProvisionedThroughput': {u'LastDecreaseDateTime': datetime.datetime(1970, 1, 1, 8, 0, tzinfo=tzlocal()),
   u'LastIncreaseDateTime': datetime.datetime(1970, 1, 1, 8, 0, tzinfo=tzlocal()),
   u'NumberOfDecreasesToday': 0,
   u'ReadCapacityUnits': 1,
   u'WriteCapacityUnits': 1},
  u'TableArn': u'arn:aws:dynamodb:ddblocal:000000000000:table/Music',
  u'TableName': u'Music',
  u'TableSizeBytes': 0,
  u'TableStatus': u'ACTIVE'}}

Delete table

When you no longer need a table and want to discard it permanently, you can use DeleteTable:

Once the table is deleted, it cannot be restored. (Some relational databases allow revocation of DROP TABLE operations)

{
    TableName: "Music"
}

Python Example

boto3

from __future__ import print_function # Python 2/3 compatibility
import boto3

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

table = dynamodb.Table('Music')

table.delete()

## output

{'ResponseMetadata': {
   'HTTPHeaders': {
       'content-length': '1012',
       'content-type': 'application/x-amz-json-1.0',
       'server': 'Jetty(8.1.12.v20130726)',
       'x-amz-crc32': '2473676771',
       'x-amzn-requestid': '84938373-870f-420f-b19e-4de2c6301743'},
   'HTTPStatusCode': 200,
   'RequestId': '84938373-870f-420f-b19e-4de2c6301743',
   'RetryAttempts': 0},
   u'TableDescription': {
   ...
   }
}

Modify table

If you want to adjust a table after it is created, you can use the Update Table command

When we modify the table, we can only do one operation at a time:

* Modify the default throughput.
* Open or stop using Streams.
* Delete a global headphone index.
* Create a global secondary index. When the index starts background execution, you can use Update Table for the next operation.

UpdateTable is an asynchronous operation; when it starts executing, the state of the table changes from ACTIVE to UPDATING.

The request grammar is:

{
   "AttributeDefinitions": [ 
      { 
         "AttributeName": "string",
         "AttributeType": "string"
      }
   ],
   "GlobalSecondaryIndexUpdates": [ 
      { 
         "Create": { 
            "IndexName": "string",
            "KeySchema": [ 
               { 
                  "AttributeName": "string",
                  "KeyType": "string"
               }
            ],
            "Projection": { 
               "NonKeyAttributes": [ "string" ],
               "ProjectionType": "string"
            },
            "ProvisionedThroughput": { 
               "ReadCapacityUnits": number,
               "WriteCapacityUnits": number
            }
         },
         "Delete": { 
            "IndexName": "string"
         },
         "Update": { 
            "IndexName": "string",
            "ProvisionedThroughput": { 
               "ReadCapacityUnits": number,
               "WriteCapacityUnits": number
            }
         }
      }
   ],
   "ProvisionedThroughput": { 
      "ReadCapacityUnits": number,
      "WriteCapacityUnits": number
   },
   "StreamSpecification": { 
      "StreamEnabled": boolean,
      "StreamViewType": "string"
   },
   "TableName": "string"
}

Python Example

boto3

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


table = db3.meta.client.update_table(
    TableName='Music',
    AttributeDefinitions=[
        { 
            'AttributeName': "Artist", 
            'AttributeType': "S" 
        },
        { 
            'AttributeName': "SongTitle", 
            'AttributeType': "S" 
        }
    ],
    ProvisionedThroughput={       
        'ReadCapacityUnits': 10, 
        'WriteCapacityUnits': 10
    }
)

db3.meta.client.describe_table(TableName='Music')

Looking at the Music table now shows that the default throughput has been modified to 10

DynamoDB UpdateTable operation

In the next article, we will conclude the most commonly used part of DynamoDB, the basic operation of the project (CRUD).

Posted by aaronrb on Sun, 07 Apr 2019 08:45:31 -0700