このレッスンでは、DynamoDB を使用したデータの挿入と取り出しの簡単な例を見ていきます。CreateTable API を使用して DynamoDB テーブルを作成し、次に BatchWriteItem API 呼び出しを使用していくつかの項目を挿入します。それから、GetItem API 呼び出しを使用して各項目を取り出します。これらの例を見ていく前に、サンプルのオンラインブックストアアプリケーションで使用するデータモデルを説明します。

この後のモジュールで、Query API 呼び出しを使用して複数の項目を一度に取り出す方法と、セカンダリインデックスを使用して別のクエリパターンを有効にする方法を説明します。テーブルの既存の項目を更新する方法もご紹介します。

モジュールの所要時間: 15 分


次に示す DynamoDB の概念はこのモジュールで重要な役割を果たします。

  • テーブル: DynamoDB データレコードの集合。
  • 項目: DynamoDB テーブル内の 1 つのデータレコード。リレーショナルデータベースの行に相当します。
  • 属性: 項目についての 1 つのデータ要素。リレーショナルデータベースの列に相当します。ただし、リレーショナルデータベースの列と違って、属性にはこのモジュールの後半に説明するプライマリキー以外、テーブル作成時に指定する必要はありません。属性は文字列、整数、ブール値などの簡単なタイプの場合も、リストやマップなどの複雑なタイプの場合もあります。
  • プライマリキー: プライマリキーは DynamoDB テーブル内の 1 つの項目を示す、一意の識別子です。プライマリキーの名前とタイプはテーブル作成時に指定する必要があり、また特定のタイプのプライマリキーは、テーブルに書き込まれる各項目に含まれる必要があります。単一のプライマリキーは単一の属性で構成され、複合プライマリキーはパーティションキーおよびソートキーという 2 つの属性で構成されます。例えば、「UserID」を識別子として単一のプライマリキーを作成することができ、「UserID」と「Creation_Date」を項目の識別子として複合プライマリキーを作成することができます。

アプリケーションを構築するとき、アプリケーションロジックに必要なデータモデルのデザインには常に時間をかけるべきです。このデータモデルデザインでは、アプリケーションでデータの読み込みと書き込みのどちらにも必要なデータアクセスのニーズを考慮する必要があります。

DynamoDB は非リレーショナルデータベースです。非リレーショナルデータベースでは、テーブル作成時に完全なスキーマを事前に定義する必要がありません。必要なのは、テーブルのプライマリキーを指定することだけです。プライマリキーによって、テーブルの各レコードは一意に識別されます。これによりデータモデルのデザインに必要な先行投資の費用を削減できます。アプリケーションのニーズが変わったときに簡単にスキーマを修正できるからです。

このチュートリアルの「アプリケーションバックグラウンド」セクションでご説明した通り、今回のアプリケーションのニーズは、個々の本をタイトルと著者で取り出すことです。タイトルと著者の組み合わせは本の一意の識別子であるため、この属性をテーブルのプライマリキーとして使用できます。アプリケーションではさらに、歴史や伝記といった本のカテゴリーに関する情報だけでなく、在庫システムで項目番号にマッピングされた販売している本のフォーマット (ハードカバー、ペーパーバック、オーディオブックなど) も保存する必要があります。

これらのニーズを念頭に置きながら、テーブルに次のスキーマを使用できます。

  • タイトル (文字列): 本のタイトル
  • 著者 (文字列): 本の著者
  • カテゴリ (文字列): 歴史、伝記、SFなどの本のカテゴリー
  • フォーマット (マップ): 販売中のさまざまなフォーマット (ハードカバー、ペーパーバック、オーディオブックなど) と在庫システムでの項目番号

次のステップでは、テーブルの複合プライマリキー (著者タイトル) を指定してテーブルを作成します。次に、いくつかの項目をテーブルにロードして、テーブルの各項目を読み込みます。


  • ステップ 1:DynamoDB テーブルを作成する

    ダウンロードしたディレクトリには、CreateTable API を使用して ブックテーブルを作成する create_table.py スクリプトが含まれています。AWS Cloud9 ターミナルで次のコマンドを入力すると、このスクリプトを実行できます。

    $ python create_table.py

    AWS Cloud9 エディタで create_table.py スクリプトを開くときは、次のことにご注意ください。

    • スクリプトでは、CreateTable API 呼び出しで、KeySchema 引数にテーブルの複合プライマリキーを指定します。テーブルでは著者をハッシュキーとして、タイトルを範囲キーとして使用します。
    • スクリプトでは、読み込み性能ユニットと書き込み性能ユニットの両方を定義して、テーブルのプロビジョンドスループットを指定します。DynamoDB では読み込み性能と書き込み性能を別々に設定できるため、高いオーバープロビジョニング費用を払うことなく、アプリケーションのニーズを満たす設定を微調整できます。
  • ステップ 2:項目をテーブルにロードする

    このステップでは、テーブルにいくつかの本をロードします。AWS Cloud9 ターミナルで次のコマンドを実行します。
    $ python insert_items.py
    このコマンドは次のスクリプトを実行します。
    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('Books')
    
    with table.batch_writer() as batch:
        batch.put_item(Item={"Author": "John Grisham", "Title": "The Rainmaker",
            "Category": "Suspense", "Formats": { "Hardcover": "J4SUKVGU", "Paperback": "D7YF4FCX" } })
        batch.put_item(Item={"Author": "John Grisham", "Title": "The Firm",
            "Category": "Suspense", "Formats": { "Hardcover": "Q7QWE3U2",
            "Paperback": "ZVZAYY4F", "Audiobook": "DJ9KS9NM" } })
        batch.put_item(Item={"Author": "James Patterson", "Title": "Along Came a Spider",
            "Category": "Suspense", "Formats": { "Hardcover": "C9NR6RJ7",
            "Paperback": "37JVGDZG", "Audiobook": "6348WX3U" } })
        batch.put_item(Item={"Author": "Dr. Seuss", "Title": "Green Eggs and Ham",
            "Category": "Children", "Formats": { "Hardcover": "GVJZQ7JK",
            "Paperback": "A4TFUR98", "Audiobook": "XWMGHW96" } })
        batch.put_item(Item={"Author": "William Shakespeare", "Title": "Hamlet",
            "Category": "Drama", "Formats": { "Hardcover": "GVJZQ7JK",
            "Paperback": "A4TFUR98", "Audiobook": "XWMGHW96" } })
    

    前のスクリプトでご説明した通り、BatchWriteItem API を使用して 5 冊の本をテーブルにロードします。それぞれの本にはプライマリキーとして著者タイトル属性が、本に関する追加情報としてカテゴリーフォーマット属性が含まれています。各属性にはタイプがあり、カテゴリー属性の文字列のような簡単なタイプの場合も、フォーマット属性のマップのような複雑なタイプの場合もあります。

    Boto 3 クライアントライブラリを使用して HTTP API 経由でデータを挿入したことにご注意ください。すべてのデータアクセスと操作リクエストはリレーショナルデータベース管理システムで一般的なデータベースへの持続的接続を維持せずに、HTTP リクエストを通じて行われます。

  • ステップ 3:テーブルから項目を取り出す

    GetItem API リクエストを使用して任意の項目のプライマリキーを指定すると、1 冊の本を取り出せます。

    AWS Cloud9 ターミナルで次のコマンドを実行します。

    $ python get_item.py

    このコマンドは次のスクリプトを実行して 1 つの項目を取り出します。取り出すのはジョン・グリシャムの『レインメーカー』という本です。

    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('Books')
    
    resp = table.get_item(Key={"Author": "John Grisham", "Title": "The Rainmaker"})
    
    print(resp['Item'])

    ターミナルには、テーブルから取り出した本のデータすべてが出力されます。

    $ python get_item.py
    {'Title': 'The Rainmaker', 'Formats': {'Hardcover': 'J4SUKVGU', 'Paperback': 'D7YF4FCX'}, 'Author': 'John Grisham', 'Category': 'Suspense'}

    テーブルの各項目はプライベートキーによって一意に識別されるため、GetItem API 呼び出しによりテーブルから返される項目は、多くても必ず 1 つになります。


    次のモジュールでは、単一の API 呼び出しで DynamoDB テーブルから複数の項目を取り出す方法をご説明します。セカンダリインデックスを使用してテーブルで複数のデータアクセスパターンを有効にする方法もご説明します。