2013-05-17 105 views
14

是否有人對AWS Java SDK 1.4.2(及更高版本)中的DynamoDB的新名稱空間(com.amazonaws.services.dynamodbv2)和接口進行了更改?根據the 1.4.2 release notes,本地二級指標的發佈顯然需要改變。AWS Java SDK中DynamoDB v2的遷移詳情?

是否有人發現了一份指南,詳細說明了遷移現有代碼所發生的變化以及需要做什麼?我正在嘗試確定何時最好對現有代碼庫進行此更改。

回答

17

DynamoDB的新dynamodbv2命名空間引入了以下不兼容的改變(在它們不是簡單地添加劑,並且需要更改代碼轉換到新的命名空間):

  • HashKeyElementRangeKeyElement替換爲地圖<字符串,AttributeValue>。這包括名爲ExclusiveStartKey,LastEvaluatedKey密鑰的結構。這種變化對代碼的主要影響是,現在爲了調用GetItem,例如,您的代碼需要知道主鍵的屬性名稱,而不僅僅是主鍵值。
  • 查詢現在使用的類型KeyCondition地圖<字符串,條件>來指定,而不必單獨HashKeyValueRangeKeyCondition領域全面查詢。
  • CREATETABLE輸入分開的主鍵定義屬性類型定義(和創建/更新/刪除/描述響應匹配此)
  • 消耗在反應容量現在是一個結構,而不是一個單一的數,而且必須要求在請求中。在批量操作中,這是以單獨的ConsumedCapacity結構返回,而不是結果旁邊。

如果需要,可以將代碼逐步遷移到新的Java API。如果您打算向查詢本地二級索引的代碼添加功能,或者使用本地二級索引創建表,則需要爲該部分代碼使用新的API。

如果使用新API創建包含本地二級索引的表,則仍然可以使用名稱空間中現有的代碼來執行該表上的所有現有操作。作爲一個例子,PutItem與dynamodb命名空間客戶端將對使用dynamodbv2客戶端創建的表以及其他方式工作。

+0

感謝您的支持。這是一個很好的總結,幷包含了一些我不需要的特定遷移。 – mckamey

9

DynamoDB AWS的Java 1.4.1 => 1.4.2(非詳盡)遷移步驟

好了,我咬了子彈,並做到了。這是我的經驗。

首先,改變DynamoDB命名空間:

  • com.amazonaws.services.dynamodb =>com.amazonaws.services.dynamodbv2

你注意到的第一件事是有類型的缺失。最主要的是鑰匙不見了。很好的摒棄,因爲它的名字太過於通用。 它現在被替換爲Map,這對於Local Secondary Indexes(LSI)來說密鑰變得更具延展性是有意義的。 不幸的是,使用地圖和泛型一般在Java中很糟糕(請參閱紅利底部)。 withHashKeyElement/withRangeKeyElement流利的接口。

接下來,非常仔細地查找/替換其被替換泛型集合的DynamoDB類型:

  • com.amazonaws.services.dynamodb.model.Key =>Map<String, AttributeValue>
  • com.amazonaws.services.dynamodb.model.BatchResponse =>List<Map<String, AttributeValue>>
  • com.amazonaws.services.dynamodb.model.KeySchema =>List<KeySchemaElement>
  • (可能其他人,這些是我直接引用的少數幾個。)

接下來,找到所有打破的。這是一個非常手動過程,需要知道您的代碼庫和SDK相當好。 具體而言,您必須非常瞭解您的關鍵模式,因爲它是從此處開始的所有字符串。幸運的是,在我的情況下,前兩項任務分別變化約90%:

  • 發現每new Map<String, AttributeValue>,這是一個跡象表明Key前身那裏。
  • QueryRequest合併withHashKeyValue(AttributeValue)withRangeKeyCondition(Condition)進入巨型withKeyConditions(Map<String,Condition>) 這種方法是LSI的核心變化,可讓您指定散列/範圍以外的其他東西。它接受的內容比接口更具限制性,但當您考慮DynamoDB只允許查詢索引屬性時,這是合理的。
  • DynamoDBQueryExpression成爲通用的,並改變了它的接口(不知道爲什麼)。
  • KeySchemaElement不再需要AttributeType,但現在需要KeyType

最後,編譯和迴歸測試整個堆棧。

P.S.當我正在執行所有這些時,version 1.4.4.1剛剛發佈到Maven Central。


獎金

由於地圖是對Java的缺乏鬆散類型類的通用解決方案,它們無處不在。 一個小幫手lib真的可以用很長的一段時間來構建這些不太複雜的東西。 這裏是我的助手的某些位:

public class MakeJavaSuckLess { // TODO: find a shorter class name 
    public static final float MAX_LOAD_FACTOR = 1.0f; 

    /** 
    * Builds a mutable Map from an interlaced sequence of key-value pairs 
    * where keys are strings and values are VType objects 
    * @param pairs 
    * @return 
    */ 
    public static <VType> Map<String, VType> asMap(Object... pairs) { 
     return mergeMaps(null, pairs); 
    } 

    /** 
    * Builds a mutable Map from an interlaced sequence of key-value pairs 
    * where keys are strings and values are VType objects 
    * @param pairs 
    * @return 
    */ 
    public static <VType> Map<String, VType> mergeMaps(Map<String, VType> map, Object... pairs) { 
     final int length = (pairs != null) ? pairs.length/2 : 0; 
     if (map == null) { 
      // max out the load factor since most of these don't change 
      map = new HashMap<String, VType>(length, MAX_LOAD_FACTOR); 
     } 

     for (int i=0; i<length; i++) { 
      String key = asString(pairs[2*i]); 
      @SuppressWarnings("unchecked") 
      VType value = (VType)pairs[2*i+1]; 
      map.put(key, value); 
     } 
     return map; 
    } 
} 

現在創建DynamoDB鍵略少醜:

Map<String, AttributeValue> key = MakeJavaSuckLess.asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal")); 

Type erasure Java的泛型,所以這種方法的地方又醜。您有時需要明確指定VType

new GetItemRequest().withKey(MakeJavaSuckLess.<AttributeValue>asMap("hashKey", new AttributeValue("hashVal"), "rangeKey", new AttributeValue("rangeVal"))); 
+3

受此stackoverflow問題和地圖構建器提示的啓發,我寫了一篇關於使用Google Guava的Map Builders和其他一些技巧的博客文章[使用DynamoDB的Java SDK時編寫較少的代碼](https://java.awsblog.com/交/ Tx2VOZ8V9I67LLD /寫作,不太代碼時,使用最AWS-SDK-用於Java的)。我希望它有幫助! –

+0

沒有這個問題和答案,遷移我的代碼將是一場噩夢,謝謝。驚訝的亞馬遜在這個變化中突破了這麼多。 –