狠狠撸

狠狠撸Share a Scribd company logo
DynamoDBとPython
(すごい広島 with Python)
西本 卓也
@nishimotz / @24motz
株式会社シュアルタ
1
アンナほえたワン(バージョン2)
2
IchigoSoda
音センサー
sakura.io
(MQTT)
IoT Core
Slack
DynamoDB
Lambda
(Python)
Lambda
(node.js)
AWS
Amazon DynamoDB
? AWS の NoSQL データベース
? 低レイテンシー
? 無料枠
? オンデマンドキャパシティーモード
? 25GB & 読み取り 250万リクエスト/mo
3
PynamoDB
? https://github.com/pynamodb/PynamoDB
? https://dev.classmethod.jp/articles/try-pynamodb/
? https://qiita.com/ykarakita/items/2bb4c951cbcb8771c3af
4
IAMポリシーを作る
? https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/refere
nce_policies_examples_dynamodb_specific-table.html
5
読み取りたいテーブル
? datetime
? パーティションキー
? ソートキーにするべきだった
? 後述
? ISO表記の文字列として格納
6
読み取りたいテーブル
7
IAMでポリシー作成
8
作成したポリシー
9
IAMユーザーを作成
10
IAMユーザーにポリシーをアタッチ
11
アクセスキーIDとシークレットキー取得
12
WSL で venv 環境作成
13
$ python3.8 -m venv venv38
$ . venv38/bin/activate
$ python -m pip install -U pip
$ python -m pip install pynamodb boto
models.py 前半
14
import logging
from constants import (AWS_ACCESS_KEY_ID, AWS_REGION, AWS_SECRET_ACCESS_KEY,
TABLE_NAME)
from pynamodb.attributes import NumberAttribute, UnicodeAttribute
from pynamodb.models import Model
logging.basicConfig()
log = logging.getLogger("pynamodb")
log.setLevel(logging.DEBUG)
log.propagate = True
models.py クラス定義
15
class DogBark(Model):
class Meta:
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
region = AWS_REGION
table_name = TABLE_NAME
raw_timestamp = UnicodeAttribute(hash_key=True, attr_name="datetime")
value = NumberAttribute(attr_name="channel-0")
module = UnicodeAttribute()
DynamoDBテーブルの属性の名前
count メソッド
16
if __name__ == "__main__":
count = DogBark.count()
print(count)
$ python models.py
1756
scan メソッド
17
if __name__ == "__main__":
items = DogBark.scan(limit=10)
for item in items:
print(f"{item.raw_timestamp} {item.value}")
$ python models.py
2019-11-26T08:43:31Z 26
2020-03-02T05:02:24Z 9
2019-12-25T01:33:39Z 7
2020-01-04T07:19:19Z 56
2019-12-31T07:58:30Z 58
2019-11-20T09:31:43Z 23
2020-04-09T08:18:21Z 50
2020-02-22T07:50:08Z 23
2019-12-04T08:47:25Z 36
2019-12-28T18:08:47Z 386
query メソッド
? パーティションキーは完全一致しか検索できない
18
if __name__ == "__main__":
items = DogBark.query("2019-12-28T18:08:47Z")
for item in items:
print(f"{item.raw_timestamp} {item.value}")
$ python models.py
DEBUG:pynamodb.connection.base:Calling DescribeTable with arguments {'TableName': 'IchigoSoda190925'}
DEBUG:pynamodb.connection.base:Calling Query with arguments {'TableName': 'IchigoSoda190925',
'KeyConditionExpression': '#0 = :0', 'ExpressionAttributeNames': {'#0': 'datetime'}, 'Expressio
nAttributeValues': {':0': {'S': '2019-12-28T18:08:47Z'}}, 'ReturnConsumedCapacity': 'TOTAL'}
DEBUG:pynamodb.connection.base: Query consumed 0.5 units
2019-12-28T18:08:47Z 386
str を datetime として読み込む
19
from pynamodb.attributes import UTCDateTimeAttribute
class DogBark(Model):
# 略
timestamp = UTCDateTimeAttribute(hash_key=True, attr_name="datetime")
# 略
if __name__ == "__main__":
for item in DogBark.scan(limit=10):
print(f"{item.timestamp.ctime()} {item.value}")
$ python models.py
Tue Nov 26 08:43:31 2019 26
Mon Mar 2 05:02:24 2020 9
Wed Dec 25 01:33:39 2019 7
Sat Jan 4 07:19:19 2020 56
ある1日のデータを出力
20
if __name__ == "__main__":
for item in sorted(
DogBark.scan(
filter_condition=(
(datetime(2020, 4, 28, tzinfo=timezone.utc) < DogBark.timestamp) &
(DogBark.timestamp < datetime(2020, 4, 29, tzinfo=timezone.utc))
), limit=10000
), key=lambda item: item.timestamp
):
print(f"{item.timestamp} {item.value}")
$ python models.py
DEBUG:pynamodb.connection.base:Calling Scan with arguments {'TableName': 'IchigoSoda190925', 'FilterExpression': '(#0 > :0 AND #0 < :1)', 'Limit':
10000, 'ExpressionAttributeNames': {'#0':'datetime'}, 'ExpressionAttributeValues': {':0': {'S': '2020-04-28T00:00:00.000000+0000'}, ':1': {'S': '2020-
04-29T00:00:00.000000+0000'}}, 'ReturnConsumedCapacity': 'TOTAL'}
DEBUG:pynamodb.connection.base: Scan consumed 12.5 units
2020-04-28 00:23:10+00:00 10
2020-04-28 00:28:09+00:00 33
2020-04-28 02:32:48+00:00 32
2020-04-28 07:46:56+00:00 7
timestamp (datetime) がパーティションキーなので、
読み込んだものを sorted で並べ替える
考察
? scanメソッド
? フルスキャンしている
? filter_condition はフルスキャンの結果の絞り込みと思われる
? limit を減らすと複数回に分割してスキャンを実行
? フルスキャンに変わりはなさそう
? queryメソッド
? パーティションキー
? 完全一致のみ
? ソートキー(あれば)
? ソートできる
? 比較演算子でクエリーできる
21

More Related Content

200429 python