2016-04-10 15 views
7

मेरे दो समान स्कीमा हैं जहां केवल एक नेस्टेड फ़ील्ड बदलता है (इसे स्कीमा 1 में onefield और स्कीमा 2 में anotherfield कहा जाता है)।दो एवरो स्कीमा प्रोग्रामेटिक रूप से

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 
     } 
    ] 
} 

मैं प्रोग्राम के एवरो 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); 
} 

और इसका इस्तेमाल कन्वर्ट करने के लिए एक एक एवरो या json प्रतिनिधित्व में इनपुट 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(); 
} 

कि कोड की उम्मीद उत्पादन पता चलता है: {"metadata":{"onefield":null,"anotherfield":null}}। मुद्दा यह है कि मैं मर्ज किए गए स्कीमा को देखने में सक्षम नहीं हूं।

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) 

मैं इसे एवरो अनिश्चितता के सिद्धांत :) फोन: यदि मैं एक साधारण System.out.println(mergedSchema) कर मैं निम्नलिखित अपवाद मिलता है। ऐसा लगता है कि एवरो मर्ज किए गए स्कीमा के साथ काम करने में सक्षम है, लेकिन जब यह जेएसओएन को स्कीमा को क्रमबद्ध करने का प्रयास करता है तो यह विफल हो जाता है। मर्ज सरल स्कीमा के साथ काम करता है, इसलिए यह मुझे एरो 1.8.0 में एक बग की तरह लगता है।

क्या आप जानते हैं कि क्या हो रहा है या इसे कैसे हल किया जा सकता है? कोई कामकाज (उदा: वैकल्पिक Schema धारावाहिक) स्वागत है।

+0

ऐसा लगता है कि यह एवरो (1.7.6) के पिछले संस्करणों में भी हो रहा है http://mail-archives.apache.org/mod_mbox/avro-user/201406.mbox/%[email protected]। nabble.com% 3E –

उत्तर

1

मैं सुअर util वर्ग के साथ एक ही मुद्दा मिल गया ... वास्तव में वहाँ 2 कीड़े यहाँ

  • एवरो गलत स्कीमा
  • piggybank util वर्ग का उपयोग कर GenericDatumWriter के माध्यम से डाटा को क्रमानुसार की अनुमति देता है पैदा कर रहा है अवैध स्कीमा हैं क्योंकि यह सभी मर्ज किए गए क्षेत्रों के लिए एक ही नाम/नाम स्थान (मूल नाम रखने का उदाहरण)

उपयोग कर रहा है यह और अधिक जटिल परिदृश्यों के लिए ठीक से काम कर रहा है https://github.com/kite-sdk/kite/blob/master/kite-data/kite-data-core/src/main/java/org/kitesdk/data/spi/SchemaUtil.java#L511

0,123,
Schema mergedSchema = SchemaUtil.merge(s1, s2); 

अपने उदाहरण से, मैं उम्मीद है कि इस दूसरों की मदद करेगा निम्नलिखित उत्पादन

{ 
    "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 
      }, 
      { 
      "name": "anotherfield", 
      "type": [ 
       "null", 
       "string" 
      ], 
      "default": null 
      } 
     ] 
     }, 
     "default": null 
    } 
    ] 
} 

हो रही है।

+0

धन्यवाद @ लेक। मैं इसे आजमाने में सक्षम नहीं हूं, लेकिन यह वास्तव में अच्छा लगता है। –

संबंधित मुद्दे