Ho due schemi simili in cui cambia solo un campo nidificato (è chiamato onefield
nello schema1 e anotherfield
nello schema2).Unisci due schemi avro in modo programmatico
schema1
{
"type": "record",
"name": "event",
"namespace": "foo",
"fields": [
{
"name": "metadata",
"type": {
"type": "record",
"name": "event",
"namespace": "foo.metadata",
"fields": [
{
"name": "onefield",
"type": [
"null",
"string"
],
"default": null
}
]
},
"default": null
}
]
}
Schema2
{
"type": "record",
"name": "event",
"namespace": "foo",
"fields": [
{
"name": "metadata",
"type": {
"type": "record",
"name": "event",
"namespace": "foo.metadata",
"fields": [
{
"name": "anotherfield",
"type": [
"null",
"string"
],
"default": null
}
]
},
"default": null
}
]
}
sono in grado di unire programatically entrambi gli schemi utilizzando Avro 1.8.0:
Schema s1 = new Schema.Parser().parse(schema1);
Schema s2 = new Schema.Parser().parse(schema2);
Schema[] schemas = {s1, s2};
Schema mergedSchema = null;
for (Schema schema: schemas) {
mergedSchema = AvroStorageUtils.mergeSchema(mergedSchema, schema);
}
e usarlo per convertire un json ingresso in una rappresentazione Avro o json:
JsonAvroConverter converter = new JsonAvroConverter();
try {
byte[] example = new String("{}").getBytes("UTF-8");
byte[] avro = converter.convertToAvro(example, mergedSchema);
byte[] json = converter.convertToJson(avro, mergedSchema);
System.out.println(new String(json));
} catch (AvroConversionException e) {
e.printStackTrace();
}
Questo codice mostra i risultati attesi: {"metadata":{"onefield":null,"anotherfield":null}}
. Il problema è che non riesco a vedere lo schema unito. Se faccio un semplice System.out.println(mergedSchema)
ottengo la seguente eccezione:
Exception in thread "main" org.apache.avro.SchemaParseException: Can't redefine: merged schema (generated by AvroStorage).merged
at org.apache.avro.Schema$Names.put(Schema.java:1127)
at org.apache.avro.Schema$NamedSchema.writeNameRef(Schema.java:561)
at org.apache.avro.Schema$RecordSchema.toJson(Schema.java:689)
at org.apache.avro.Schema$RecordSchema.fieldsToJson(Schema.java:715)
at org.apache.avro.Schema$RecordSchema.toJson(Schema.java:700)
at org.apache.avro.Schema.toString(Schema.java:323)
at org.apache.avro.Schema.toString(Schema.java:313)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
Io lo chiamo il principio di indeterminazione avro :). Sembra che avro sia in grado di lavorare con lo schema unito, ma fallisce quando tenta di serializzare lo schema su JSON. L'unione funziona con schemi più semplici, quindi mi sembra un errore in avro 1.8.0.
Sai cosa potrebbe accadere o come risolverlo? Qualsiasi soluzione alternativa (ad esempio i serializzatori alternativi Schema
) è la benvenuta.
Sembra che stia accadendo anche nelle versioni precedenti di avro (1.7.6) http://mail-archives.apache.org/mod_mbox/avro-user/201406.mbox/%[email protected] nabble.com% 3E –