メニュー
Amazon DynamoDB
開発者ガイド (API Version 2012-08-10)

ステップ 4: データをクエリおよびスキャンする

query メソッドを使用して、テーブルからデータを取得できます。パーティションキーの値を指定する必要があります。ソートキーはオプションです。

Movies テーブルのプライマリキーは、以下の内容で構成されます。

  • year – パーティションキー。属性タイプは数値です。 

  • title – ソートキー。属性タイプは文字列です。

1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできます。たとえば、2014 年にリリースされた、主題が「A」で始まる映画を見つけることができます。

query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。

データのクエリとスキャンの詳細については、「クエリの操作」と「スキャンの使用」をそれぞれ参照してください。

ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画

このステップに含まれているプログラムは、year 1985 にリリースされたすべての映画を取得します。

  1. 次のプログラムを MoviesQuery01.py というファイルにコピーアンドペーストします。

    Copy
    from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr # Helper class to convert a DynamoDB item to JSON. 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) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') print("Movies from 1985") response = table.query( KeyConditionExpression=Key('year').eq(1985) ) for i in response['Items']: print(i['year'], ":", i['title'])

    注記

    boto3.dynamodb.conditions からインポートされた Key 関数と Attr 関数を使用すると、Boto 3 SDK により ConditionExpression が自動的に作成されます。また、文字列として ConditionExpression を指定することもできます。

    DynamoDB の使用可能な条件のリストについては、AWS SDK for Python (Boto 3) の使用開始の「DynamoDB の条件」を参照してください。

    詳細については、「条件式」を参照してください。

  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesQuery01.py

注記

前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示しています。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカンダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔軟性を提供します。詳細については、「セカンダリインデックスを使用したデータアクセス性の向上」を参照してください。

ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画

このステップに含まれているプログラムは、year 1992 にリリースされたすべての映画のうち、title が「A」~「L」で始まる映画を取得します。

  1. 次のプログラムを MoviesQuery02.py というファイルにコピーアンドペーストします。

    Copy
    from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): return str(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') print("Movies from 1992 - titles A-L, with genres and lead actor") response = table.query( ProjectionExpression="#yr, title, info.genres, info.actors[0]", ExpressionAttributeNames={ "#yr": "year" }, # Expression Attribute Names for Projection Expression only. KeyConditionExpression=Key('year').eq(1992) & Key('title').between('A', 'L') ) for i in response[u'Items']: print(json.dumps(i, cls=DecimalEncoder))
  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesQuery02.py

ステップ 4.3: スキャン

scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できます。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されます。

次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定します。

  1. 次のプログラムを MoviesScan.py というファイルにコピーアンドペーストします。

    Copy
    from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr # Helper class to convert a DynamoDB item to JSON. 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) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') fe = Key('year').between(1950, 1959); pe = "#yr, title, info.rating" # Expression Attribute Names for Projection Expression only. ean = { "#yr": "year", } esk = None response = table.scan( FilterExpression=fe, ProjectionExpression=pe, ExpressionAttributeNames=ean ) for i in response['Items']: print(json.dumps(i, cls=DecimalEncoder)) while 'LastEvaluatedKey' in response: response = table.scan( ProjectionExpression=pe, FilterExpression=fe, ExpressionAttributeNames= ean, ExclusiveStartKey=response['LastEvaluatedKey'] ) for i in response['Items']: print(json.dumps(i, cls=DecimalEncoder))

    このコードでは、以下の点に注意してください。

    • ProjectionExpression は、スキャン結果に必要な属性を指定します。

    • FilterExpression は、条件を満たした項目だけが返されるような条件を指定します。他のすべての項目は破棄されます。

    • scan メソッドは、ページという項目のサブセットを毎回返します。次に、応答の LastEvaluatedKey 値が、scan パラメーター経由で ExclusiveStartKey メソッドに渡されます。最後のページが返されると、LastEvaluatedKey は応答の一部ではなくなります。

    注記

    • ExpressionAttributeNames は、名前を置換します。year は DynamoDB の予約語であるため、これが使用されます。KeyConditionExpression を含むどの式でも直接使用することはできません。これに対処するため、式の属性名 #yr を使用できます。

    • ExpressionAttributeValues は、値を置換します。KeyConditionExpression を含むどの式にもリテラルを使用できないため、これを使用します。これに対処するため、式の属性値 :yyyy を使用できます。

  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesScan.py

注記

テーブルで作成した任意のセカンダリインデックスで Scan メソッドを使用することもできます。詳細については、「セカンダリインデックスを使用したデータアクセス性の向上」を参照してください。