ScalaからDynamoDBを扱うサンプル

More than 1 year has passed since last update.

ScalaからDynamoDB Java SDKを扱う際のサンプルです。足りないAPIは必要に応じて増やしていきます。

各APIを扱う書き方は複数あるので特定のパターンのみ記述しています。

フルのソースコードはこちら

https://github.com/Peranikov/dynamodb-scala-sample/blob/master/src/main/scala/LowLevelApiSample.scala


はじめに

aws-java-sdk-dynamodblibraryDependenciesに含めておきます。


build.sbt

libraryDependencies += "com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.29"


dynamodb-localは既に立ち上がってる前提で進めます。

AWS-CLIでサンプルとして使うDynamoDBのテーブルも先に作っておきましょう。

#!/usr/bin/env bash

export AWS_ACCESS_KEY_ID="dummy"
export AWS_SECRET_ACCESS_KEY="dummy"

aws dynamodb --endpoint-url "http://localhost:8000" create-table \
--table-name Music \
--attribute-definitions \
AttributeName=Artist,AttributeType=S \
AttributeName=SongTitle,AttributeType=S \
--key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
--provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1

AmazonDynamoDBClientとmodelをimportしておきます。

collection.JavaConversions._もimportしておくとJavaとScala間でコレクションを自動的に変換してくれるので便利です。 参考

collection.JavaConversions._は非推奨になる可能性があるので、今後はJavaConvertersを使うほうが良いそうです。 参考

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient

import com.amazonaws.services.dynamodbv2.model._

// import collection.JavaConversions._
import collection.JavaConverters._


クライアント生成

val client: AmazonDynamoDBClient = (new AmazonDynamoDBClient())

.withEndpoint("http://localhost:8000")


テーブル一覧

println(client.listTables)


テーブル情報

println(client.describeTable("Music"))


Batch Write

テーブルに複数のアイテムを一度に書き込みます。

  val batchWriteItems: java.util.List[WriteRequest] = Seq(

new WriteRequest(new PutRequest(
Map(
"Artist" -> new AttributeValue("Rainbow"),
"SongTitle" -> new AttributeValue("Kill the King"),
"Member" -> new AttributeValue(Seq(
"Ronnie James Dio",
"Ritchie Blackmore"
).asJava)
).asJava
)),
new WriteRequest(new PutRequest(
Map(
"Artist" -> new AttributeValue("Rainbow"),
"SongTitle" -> new AttributeValue("All Night Long"),
"Member" -> new AttributeValue(Seq(
"Graham Bonnet",
"Ritchie Blackmore"
).asJava)
).asJava
)),
new WriteRequest(new PutRequest(
Map(
"Artist" -> new AttributeValue("Metallica"),
"SongTitle" -> new AttributeValue("Enter Sandman"),
"Member" -> new AttributeValue(Seq(
"James Hetfield",
"Kirk Hammett"
).asJava)
).asJava
)),
new WriteRequest(new PutRequest(
Map(
"Artist" -> new AttributeValue("Deep Purple"),
"SongTitle" -> new AttributeValue("Highway Star"),
"Member" -> new AttributeValue(Seq(
"Ian Gillan",
"Ritchie Blackmore"
).asJava)
).asJava
))
).asJava

println(
client.batchWriteItem(
(new BatchWriteItemRequest())
.withRequestItems(Map("Music" -> batchWriteItems).asJava)
)
)


ハッシュキーでクエリ

ハッシュキーを指定してクエリします(prettyPrintメソッドはMapを拡張して追加しています。詳しくはコード)

val hashCondition = new Condition()

.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue("Rainbow")
)

println(
client.query(
(new QueryRequest("Music"))
.withKeyConditions(Map("Artist" -> hashCondition).asJava)
).getItems.asScala.map(_.asScala.toMap.prettyPrint)
)


クエリ + フィルター

フィルター条件を加えてクエリします

val filterCondition = new Condition()

.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue("Ronnie James Dio")
)

println(
client.query(
(new QueryRequest("Music"))
.withKeyConditions(Map("Artist" -> hashCondition).asJava)
.withQueryFilter(Map("Vocal" -> filterCondition).asJava)
).getItems.asScala.map(_.asScala.toMap.prettyPrint)
)


クエリ + リミット、 さらに続きをクエリ

リミットを掛けてクエリします

val limitQueryResult = client.query(

(new QueryRequest("Music"))
.withKeyConditions(Map("Artist" -> hashCondition).asJava)
.withLimit(1)
)
println(
limitQueryResult.getItems.asScala.map(_.asScala.toMap.prettyPrint)
)

続きがある場合、LastEvaluatedKeyが取得できるのでExclusiveStartKeyに指定して続きから取得します。

  println(

client.query(
(new QueryRequest("Music"))
.withKeyConditions(Map("Artist" -> hashCondition).asJava)
.withExclusiveStartKey(limitQueryResult.getLastEvaluatedKey)
).getItems.asScala.map(_.asScala.toMap.prettyPrint)
)


スキャン

全てのアイテムを取得します

println(

client.scan(
new ScanRequest("Music")
).getItems.asScala.map(_.asScala.toMap.prettyPrint)
)