boto3のresoureをclientに移行する為のDynamoDB Json, FilterExpression周りのTips
こんにちは、けんご(@N30nnnn)です。
2023/1にboto3のresourceインターフェースが更新されなくなるとの告知がなされ、例に漏れずclientインターフェースへの移行を進めています。
Resources - Boto3 Docs 1.26.89 documentation
AWS Python SDK(boto3)のリソース・インターフェースが改修凍結されました | DevelopersIO
その過程で dynamodbのresourceをclientに移行するの面倒くさいなと思ってたのですが、boto3に便利な変換機があったのでご紹介します。
dynamodb jsonへの変換
例えば、dynamodbの get_item()
を例に取ると、Keyに渡す値違いがあります
- resoure
{"partition_key_name": value}
- client
{"partition_key_name": {"S": value}}
上記の様にclientは型情報を付与する必要があり、変換しなければいけません。
こちらの変換は、classmethodさんの記事になってました。
DynamoDB JSONの型変換をboto3だけで行ってみる | DevelopersIO
これは下記クラスを使うと手軽に型情報の付与•除去をすることが可能です。
boto3.dynamodb.types.TypeSerializer
boto3.dynamodb.types.TypeDeserializer
from boto3.dynamodb.types import TypeSerializer, TypeDeserializer serializer = TypeSerializer() deserializer = TypeDeserializer() key = {"partition_key_name": "string-value"} key = serializer.serialize(key) # {"partition_key_name": {"S": "string-value"}} key = deserializer.deserialize(key) # {"partition_key_name": "string-value"}
これはdynamodbが対応してる型の入力は全部対応してくれ、map型などの深い構造も再帰的に行ってくれるので、とりあえずseralizer, deserializer に突っ込んで置けばよくて楽です。
FilterExpressionの変換
dynamodbのresourceインターフェースにおける scan
や query
などは、下記のようなFilterexpressionを指定すると取得されるデータを絞れます。
FilterExpression = ( Attr('attr_name1').contains('xxxxxx') & Attr('attr_name2').lt(100) )
これはclientインターフェースに置いてはプレースホルダを用いて式•変数名•値を別々に渡す必要がありますが(詳細略)、 boto3.dynamodb.conditions.ConditionExpressionBuilder
を用いると上記条件式を簡単にclientインターフェースに対応することが可能になります
from boto3.dynamodb.conditions import Attr, ConditionExpressionBuilder builder = ConditionExpressionBuilder() condition = ( Attr('attr_name1').contains('xxxxxx') & Attr('attr_name2').lt(100) ) condition_expr, attr_name_placeholders, attr_value_placeholders = builder.build_expression(condition) # condition_expr: '(contains(#n0, :v0) AND #n1 < :v1)' # attr_name_placeholders: {'#n0': 'attr_name1', '#n1': 'attr_name2'} # attr_value_placeholders: {':v0': 'xxxxxx', ':v1': 100}