Сведения о миграции для DynamoDB v2 в AWS Java SDK? - программирование
Подтвердить что ты не робот

Сведения о миграции для DynamoDB v2 в AWS Java SDK?

Кто-нибудь внес изменения в новые пространства имен (com.amazonaws.services.dynamodbv2) и интерфейсы для DynamoDB в AWS Java SDK 1.4.2 (и позже)? Выпуск локальных вторичных индексов, по-видимому, потребовал нарушения изменений примечаний к выпуску 1.4.2.

Кто-нибудь нашел руководство, в котором подробно описано, что изменилось и что должно произойти, чтобы перенести существующий код? Я пытаюсь решить, когда лучше всего сделать это изменение для существующей базы кода.

4b9b3361

Ответ 1

Новое пространство имен dynamodbv2 DynamoDB вводит следующие несовместимые изменения (в том смысле, что они не являются просто аддитивными и требуют изменения кода для переключения в новое пространство имен):

  • HashKeyElement и RangeKeyElement заменяются на Map < String, AttributeValue > . Сюда входят структуры ExclusiveStartKey, LastEvaluatedKey и Key. Основное влияние на код с этим изменением заключается в том, что теперь для вызова GetItem, например, ваш код должен знать имена атрибутов первичных ключей, а не только значения первичного ключа.
  • Теперь Query использует KeyCondition типа Map < String, Condition > , чтобы указать полный запрос, вместо отдельных полей HashKeyValue и RangeKeyCondition.
  • Ввод CreateTable отделяет определения типа атрибута от определений первичных ключей (и создает/обновляет/удаляет/описывает ответы).
  • Потребляемая мощность в ответах теперь представляет собой структуру вместо одного номера и должна запрашиваться в запросе. В пакетных операциях это возвращается в отдельной структуре ConsumedCapacity, а не рядом с результатами.

При необходимости можно перенести свой код на новый API Java по мере необходимости. Если вы планируете добавить функциональность к вашему коду, который запрашивает локальные вторичные индексы или создает таблицы с локальными вторичными индексами, вам нужно будет использовать новый API для этой части вашего кода.

Если вы создаете таблицу с локальными вторичными индексами с новым API, вы все равно можете использовать свой существующий код в пространстве имен dynamodb для выполнения всех существующих операций в этой таблице. Например, PutItem с клиентом пространства имен dynamodb будет работать против таблиц, созданных с помощью клиента dynamodbv2, а также наоборот.

Ответ 2

DynamoDB AWS Java 1.4.1 = > 1.4.2 (не исчерпывающие) шаги миграции

Хорошо, я укусил пулю и сделал это. Вот мой опыт.

Сначала измените пространство имен DynamoDB:

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

Первое, что вы заметили, - это недостающие типы. Самый главный из них - Key. Хорошее избавление, поскольку оно было слишком общим названием. Теперь он заменен на карту, которая имеет смысл, поскольку ключи становятся намного более податливыми с Local Secondary Indexes (LSI). К сожалению, работа с картами и дженериками в целом отстой в Java (см. Бонус внизу). Gone - это плавные интерфейсы 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. Пока я выполнял все это, версия 1.4.4.1 была выпущена только в Maven Central.


Bonus

Так как Maps - это общее решение для 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"));

Тип erasure в Java-дженериках делает это снова уродливым в местах. Иногда вам нужно явно указать VType:

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