DynamoDB / Scanamo:提供的关键元素与架构不匹配

Posted

技术标签:

【中文标题】DynamoDB / Scanamo:提供的关键元素与架构不匹配【英文标题】:DynamoDB / Scanamo : The provided key element does not match the schema 【发布时间】:2017-10-21 19:25:38 【问题描述】:

我一直在尝试通过 Scanamo 库使用 DynamoDB。我的 scala 代码如下所示:

package my.package

import com.amazonaws.ClientConfiguration
import com.amazonaws.regions.Region, Regions
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
import com.gu.scanamo._
import com.gu.scanamo.syntax._
import com.amazonaws.auth.AWSStaticCredentialsProvider, BasicAWSCredentials
import com.amazonaws.services.dynamodbv2.datamodeling._

object MusicService 

  def main(args: Array[String]): Unit = 
    val musicService = new MusicService
    musicService.getAlbums()
  



class MusicService 

  def getAlbums() 

    val awsCreds = new BasicAWSCredentials("my","creds")
    val client = AmazonDynamoDBClient
      .builder()
      .withRegion(Regions.EU_WEST_2)
      .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
      .build();


    case class Music(@DynamoDBIndexRangeKey(attributeName = "Artist") 
        artist: String, @DynamoDBIndexHashKey(attributeName = "SongTitle") songTitle: String);

    val table = Table[Music]("Music")

    val putOp = table.putAll(Set(
      Music("The Killers", "Sam's Town"),
      Music("The Killers", "Spaceman")
    ))
    Scanamo.exec(client)(putOp)


执行 putOp 时出现此错误:

Exception in thread "main" com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException: The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 0KAFH90JO39COO143LC5H6RPPNVV4KQNSO5AEMVJF66Q9ASUAAJG)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1638)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1303)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1055)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:2186)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:2162)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeBatchWriteItem(AmazonDynamoDBClient.java:575)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.batchWriteItem(AmazonDynamoDBClient.java:551)
at com.gu.scanamo.ops.ScanamoInterpreters$$anon$1.apply(ScanamoInterpreters.scala:51)
at com.gu.scanamo.ops.ScanamoInterpreters$$anon$1.apply(ScanamoInterpreters.scala:30)
at cats.free.Free.$anonfun$foldMap$1(Free.scala:126)
at cats.package$$anon$1.tailRecM(package.scala:41)
at cats.free.Free.foldMap(Free.scala:124)
at cats.free.Free.$anonfun$foldMap$1(Free.scala:127)
at cats.package$$anon$1.tailRecM(package.scala:41)
at cats.free.Free.foldMap(Free.scala:124)
at com.gu.scanamo.Scanamo$.exec(Scanamo.scala:17)
at my.package.MusicService.getAlbums(MusicService.scala:39)
at my.package.MusicService$.main(MusicService.scala:14)
at my.package.MusicService.main(MusicService.scala)

我在 DynamoDB 上的表结构非常简单,如下所示:

Table name: Music
Partition key: Artist
Sort key: SongTitle

就是这样。

请您给我一些指导,为什么这会失败以及我可以做些什么来解决它?

【问题讨论】:

【参考方案1】:

首先,您需要交换 @DynamoDBIndexHashKey@DynamoDBIndexRangeKey@DynamoDBIndexHashKey 应该是哈希键 - 艺术家,@DynamoDBIndexRangeKey 应该是排序键 - songTitle)。

您还提到 Artist 是 Partition 键,SongTitle 是 Sort 键。那么为什么你使用@DynamoDBIndexHashKey@DynamoDBIndexRangeKey?我猜你需要 @DynamoDBHashKey@DynamoDBRangeKey 代替(以防艺术家和歌曲标题不是索引)。

【讨论】:

感谢您的回复。我使用了不正确的注释。然而,不管注释没有得到尊重,所以我仍然遇到同样的问题。我通过更改案例类中的字段名称以匹配 DynamoDB 表中的字段名称来解决此问题,但这并不理想:case class Music(Artist: String, SongTitle: String)

以上是关于DynamoDB / Scanamo:提供的关键元素与架构不匹配的主要内容,如果未能解决你的问题,请参考以下文章

AWS DynamoDB - 提供的关键元素与架构不匹配

AWS dynamoDB - batchWrite - 提供的关键元素与架构不匹配

DynamoDB AmazonServiceException:提供的关键元素与架构不匹配

从 DynamoDB 获取项目时出现“提供的关键元素与架构不匹配”错误

DynamoDB - 关键元素与架构不匹配

我们可以通过 AWS SDK 使用 GSI 删除 DynamoDB 中的项目吗?