DynamoDBからqueryでデータを取り出すPythonのプログラム
Contents
DynamoDB
今回は query を使ってデータを取り出すPythonのプログラムについて分かったことを記事にしておく。
以前のtablescanと使ったDynamoDBに関する記事は以下の通り。
事前準備
DynamoDBにアクセス用のアクセスキーIDの作成やPythonからDynamoDBにアクセスするために必要なモジュール(Boto3)のインストールについては以前の記事を参照。
プログラム
実行環境
OS | Windows10 Pro及びHome 64Bit |
Python | Ver3.7.7(Anaconda上で実行) |
プログラムソースコード
queryを使ったプログラムは以下の通り。
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 29 14:55:27 2020
@author: Souichirou.Kikuchi
"""
import json
from typing import List
from decimal import Decimal
import boto3
from boto3.resources.base import ServiceResource
from boto3.dynamodb.types import Binary
from boto3.dynamodb.conditions import Key, Attr # Query用
def scan_table(table_name: str, dynamodb: ServiceResource) -> List[dict]:
table = dynamodb.Table(table_name) # DynamoDBテーブル読み込み
resp = table.query(
KeyConditionExpression=Key('tempkeyindex').eq('2020-07-10 21:24:01SKRPZ0002'),
FilterExpression=Attr('min_temp').gte(5)
)
table_items = resp['Items'] # 1回のTableScanで取得できる件数に限界があるので複数回に渡って取得する
while 'LastEvaluatedKey' in resp: # 最後まで読み込み
resp = table.query(
KeyConditionExpression=Key('tempkeyindex').eq('2020-07-10 21:24:01SKRPZ0002'),
FilterExpression=Attr('min_temp').gte(5),
ExclusiveStartKey=resp['LastEvaluatedKey']
)
table_items.extend(resp['Items'])
return table_items
def default_proc(obj) -> object: # 型変換
if isinstance(obj, Decimal): # Decimalであればintかfloatに変換
if int(obj) == obj:
return int(obj)
else:
return float(obj)
elif isinstance(obj, Binary):
return obj.value
elif isinstance(obj, bytes):
return obj.decode(encoding='default')
elif isinstance(obj, set):
return list(obj)
try:
return str(obj)
except Exception:
return None
def put_data(table_items: List[dict]) -> None:
with open('./export.json', 'w') as f:
json.dump(table_items, f, default=default_proc, ensure_ascii=False, sort_keys=True, indent=4)
if __name__ == '__main__':
table_name = 'テーブル名'
dynamodb = boto3.resource('dynamodb',
aws_access_key_id='アクセスキーID',
aws_secret_access_key='シークレットアクセスキー',
region_name='リージョン')
table_items = scan_table(table_name, dynamodb)
put_data(table_items)
補足説明
プライマリーキー
今回読み込んだテーブルには以下のキーを設定している。
- tempkeyindex:プライマリーパーティションキー
- clientid:プライマリーソートキー
KeyConditionExpression
KeyConditionExpressionではプライマリパーティションキー及びプライマリーソートキーを指定する。
プライマリパーティションキーはeq(イコール)のみ指定可能。
プライマリーソートキーを&(アンド条件)で指定する事も可能だがプライマリパーティションキーが指定されていることが条件でソートキーのみを指定することは出来ない。
尚、ソートキーの方はbetween、gte(大なりイコール)等の指定が可能。
KeyConditionExpression=Key('tempkeyindex').eq('2020-07-10 21:24:01SKRPZ0002') & Key('clientid').between('SKRPZ0002','SKRPZ0003')
FilterExpression
FilterExpressionはプライマリパーティションキー、プライマリーソートキー以外の項目が指定できる。
しかしKeyConditionExpressionが指定されている事が前提でFilterExpressionのみを指定する事が出来なかった。
またFloat型の項目は指定出来ず、”DECIMAL型にして下さい”とのエラーメッセージが表示されてしまった。
- eq:イコール
- gt:大なり
- gte:大なりイコール
- contains:含む
- lt:小なり
- lte:小なりイコール
等が指定できる。
この記事が何処かで誰かの役に立つことを願っている。
尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。
最近のコメント