Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

200429 python

226 views

Published on

DynamoDB と Python
西本 卓也 @nishimotz / @24motz
株式会社シュアルタ
2020-04-29 すごい広島 with Python オンライン
3月の続き&発表後に加筆しています

Published in: Technology
  • Be the first to comment

  • Be the first to like this

200429 python

  1. 1. DynamoDBとPython (すごい広島 with Python) 西本 卓也 @nishimotz / @24motz 株式会社シュアルタ 1
  2. 2. アンナほえたワン(バージョン2) 2 IchigoSoda 音センサー sakura.io (MQTT) IoT Core Slack DynamoDB Lambda (Python) Lambda (node.js) AWS
  3. 3. Amazon DynamoDB • AWS の NoSQL データベース • 低レイテンシー • 無料枠 • オンデマンドキャパシティーモード • 25GB & 読み取り 250万リクエスト/mo 3
  4. 4. PynamoDB • https://github.com/pynamodb/PynamoDB • https://dev.classmethod.jp/articles/try-pynamodb/ • https://qiita.com/ykarakita/items/2bb4c951cbcb8771c3af 4
  5. 5. IAMポリシーを作る • https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/refere nce_policies_examples_dynamodb_specific-table.html 5
  6. 6. 読み取りたいテーブル • datetime • パーティションキー • ソートキーにするべきだった • 後述 • ISO表記の文字列として格納 6
  7. 7. 読み取りたいテーブル 7
  8. 8. IAMでポリシー作成 8
  9. 9. 作成したポリシー 9
  10. 10. IAMユーザーを作成 10
  11. 11. IAMユーザーにポリシーをアタッチ 11
  12. 12. アクセスキーIDとシークレットキー取得 12
  13. 13. WSL で venv 環境作成 13 $ python3.8 -m venv venv38 $ . venv38/bin/activate $ python -m pip install -U pip $ python -m pip install pynamodb boto
  14. 14. 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
  15. 15. 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テーブルの属性の名前
  16. 16. count メソッド 16 if __name__ == "__main__": count = DogBark.count() print(count) $ python models.py 1756
  17. 17. 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
  18. 18. 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
  19. 19. 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
  20. 20. ある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 で並べ替える
  21. 21. 考察 • scanメソッド • フルスキャンしている • filter_condition はフルスキャンの結果の絞り込みと思われる • limit を減らすと複数回に分割してスキャンを実行 • フルスキャンに変わりはなさそう • queryメソッド • パーティションキー • 完全一致のみ • ソートキー(あれば) • ソートできる • 比較演算子でクエリーできる 21

×