Avro: сохранение обратной возможности с использованием значения по умолчанию в новом поле без использования модуля записи / старой схемы

AVRO может справиться с наиболее распространенной прямой и обратной совместимостью. Но ему как-то нужна схема писателя при чтении данных с использованием более новой схемы.

Сказать, что есть старая схема:

{
  "type": "record",
  "name": "com.test.Contact",
  "fields": [
    {
      "name": "address",
      "type": "string"
    }
  ]
}

Если для декодирования байтов, записанных старой схемой, используется следующая новая схема, необходимо иметь как старую, так и новую схему.

{
  "type": "record",
  "name": "com.test.Contact",
  "fields": [
    {
      "name": "address",
      "type": "string"
    },
    {
      "name": "phone",
      "type": ["null", "string"],
      "default": null
    }
  ]
}

Код для чтения

    static void sede3() throws IOException {
        System.out.println("----------------------sede3---------------------");
        Schema.Parser parserNew = new Schema.Parser();
        Schema.Parser parserOld = new Schema.Parser();
        Schema addrSchemaNew = parserNew.parse(AppMainCore.class.getClassLoader()
                .getResourceAsStream("compatibility-new.schema.json"));
        Schema addrSchemaOld = parserOld.parse(AppMainCore.class.getClassLoader()
                .getResourceAsStream("compatibility-old.schema.json"));

        GenericRecord addressOld = new GenericData.Record(addrSchemaOld);
        addressOld.put("address", "ABCDEF");
        // Generate bytes using old schema.
        ByteArrayOutputStream bbos = new ByteArrayOutputStream();
        Encoder encoder = EncoderFactory.get().binaryEncoder(bbos, null);
        DatumWriter<GenericRecord> writer = new GenericDatumWriter<>(addrSchemaOld);
        writer.write(addressOld, encoder);
        encoder.flush();
        bbos.close();
        byte[] oldBytes = bbos.toByteArray();
        System.out.println(Hex.encodeHexString(oldBytes) + " is old record bytes");
        // Try to deserialize old bytes using new schema, with old schema's help
        DatumReader<GenericRecord> readerGood = new GenericDatumReader<>(addrSchemaOld, addrSchemaNew);
        Decoder decoderGood = DecoderFactory.get().binaryDecoder(oldBytes, null);
        GenericRecord goodAddress = readerGood.read(null, decoderGood);

        System.out.println(goodAddress + " is record from old bytes using new schema");
    }

Я пытаюсь десериализовать старые байты, используя новую схему, без помощи старой схемы.

лайк:

DatumReader<GenericRecord> readerGood = new GenericDatumReader<>(addrSchemaNew);

Но нет

DatumReader<GenericRecord> readerGood = new GenericDatumReader<>(addrSchemaOld, addrSchemaNew);

Поддерживается ли это в Avro?

1 ответ

Я не думаю, что это возможно, см. Документацию здесь: https://avro.apache.org/docs/1.8.2/spec.html. Avro требуется как старая, так и новая схема для выполнения преобразования.

Другие вопросы по тегам