tapitapi’s blog

1日1杯タピオカ!エンジニア

【AWS DynamoDB】Search item (query) をPythonで行う

今回はPythonでテーブルデータを検索する方法をご紹介します。

(テーブル削除についてはこちら

(テーブル作成についてはこちら

 (テーブルにデータ挿入についてはこちら

 

リファレンス

boto3.amazonaws.com

 

まず、AWS CLIを使用できるようにする

tapitapi.hatenadiary.com

 

boto3を使用できるように、pip install

pip install boto3

 

テーブル作成

(下記では例として、「table2」というtableを作成します。カラムは「column1」「column2」「column3」, インデックスは「column1」と「column3」のインデックスを一つ作成します)

tapitapi.hatenadiary.com

 

テーブルにデータ挿入

tapitapi.hatenadiary.com

 

挿入後のテーブル(table2)の状態は下記のようになります

f:id:kayo445:20200721192008p:plain

 

 

query_items.py作成

import boto3

 

if __name__ == "__main__":

 session = boto3.Session(profile_name='default')
 client = session.client('dynamodb', region_name='us-east-2など、地域名')

 

   result = [] // 結果格納用配列

   response = client.query(
      TableName="Table2",
      KeyConditionExpression="column1 = :column1 and column2 = :column2",
      ExpressionAttributeValues={
           ":column1":{"S":"Data3"},
           ":column3":{"S":"BB"},
           ":column2":{"S":"Data4"}
      },
      FilterExpression="column3 = :column3",
      ProjectionExpression="column3, column7"
  )


  result.extend(response) // 結果をresultに格納

 

  if "LastEvaluatedKey" in response:
    nextKey = response["LastEvaluatedKey"]
    while nextKey:
           query_result = client.query(
             TableName="Table2",
             KeyConditionExpression="column1 = :column1 and column2 = :column2",
             ExpressionAttributeValues={
                          ":column1":{"S":"Data3"},
                          ":column3":{"S":"BB"},
                          ":column2":{"S":"Data4"}
             },
             FilterExpression="column3 = :column3",
             ProjectionExpression="column3, column7",
             ExclusiveStartKey=nextKey
             )
             result.extend(query_result) // 結果をresultに格納


             if not "LastEvaluatedKey" in query_result:
                break
             else:
               nextKey = query_result["LastEvaluatedKey"]
lg.info(result)

 

 

結果:

'Items':

[{'column3': {'S': 'BB'}, 'column7': {'L': [{'S': 'Cookies'}, {'S': 'Coffee'}, {'N': '3.14159'}]}}],

'Count': 1,

'ScannedCount': 1,

'ResponseMetadata': {'RequestId': 'XXX', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Tue, 28 Jul 2020 10:29:48 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '126', 'connection': 'keep-alive', 'x-amzn-requestid': 'xxx', 'x-amz-crc32': '648438377'}, 'RetryAttempts': 0}}

 

解説:

【検索結果Key】

Items:

検索でヒットしたデータが格納される

 

LastEvaluatedKey:

一度の検索で返ってくる結果は1MBまで。今回の検索ではこのKeyは出現しないが、検索結果が1MBを超えると、ここに、次の検索を始める最初のKeyが格納される

 

【Queryに指定するパラメタ】

TableName:

検索したいテーブル名を指定。

今回はTable2テーブルに対して検索

 

KeyConditionExpression:

テーブルを作成時にKeySchemaに指定したカラムに対するQueryを記載。

今回はcolumn1カラムの値がData3、かつ、column2カラムの値がData4のデータを検索。:column1と:column2は変数になっており、ExpressionAttributeValuesで変数の定義を行う

 

ExpressionAttributeValues:

検索用に使用する変数(値用)を定義。

今回は、:column1=Data3(文字列)、:column3=BB(文字列)、:column2=Data4(文字列)の三つの変数を定義。

 

FilterExpression:

KeySchemaに指定したカラム以外に対するQueryを記載。

今回は、KeyConditionExpressionで検索されたデータの中から、column3カラムの値がBBのデータを検索。

 

ProjectionExpression:

検索結果で必要なカラムを指定。指定しない場合は、全てのカラムが検索結果として出てくる。

今回はcolumn3とcolumn7を指定。

 

ExclusiveStartKey:

前回の検索でLastEvaluatedKeyが返された場合、ここにLastEvaluatedKeyの値をセットすると、続きの検索ができる

 

以上ですー!!

 

下記レポジトリでデータを入れるツール(dynamoDB/search_dynamodb_tables_json.py)を作成しましたので、使ってみてください^^

github.com

 

今後もDynamoDBに限らず、 LambdaやAPI Gatewayなど他のAWSサービス用ツールも作成していく予定です。

プルリクなどもいただけると嬉しいです!

 

おやすみなさい。