2012-02-23 14 views
10

Zastanawiam się, czy możliwe jest posiadanie opcjonalnej tablicy. Załóżmy schemat tak:opcjonalna tablica w schemacie avro

{ 
    "type": "record", 
    "name": "test_avro", 
    "fields" : [ 
     {"name": "test_field_1", "type": "long"}, 
     {"name": "subrecord", "type": [{ 
     "type": "record", 
     "name": "subrecord_type", 
      "fields":[{"name":"field_1", "type":"long"}] 
      },"null"] 
    }, 
    {"name": "simple_array", 
    "type":{ 
     "type": "array", 
     "items": "string" 
     } 
    } 
    ] 
} 

Próbuje napisać Avro nagrywanie bez „simple_array” spowodowałoby NPE w datafilewriter. Dla subrecord to jest po prostu w porządku, ale gdy próbuję zdefiniować tablicę jako opcjonalne:

{"name": "simple_array", 
"type":[{ 
    "type": "array", 
    "items": "string" 
    }, "null"] 

To nie spowodować NPE jednak wyjątek środowiska wykonawczego:

AvroRuntimeException: Not an array schema: [{"type":"array","items":"string"},"null"] 

Dzięki.

Odpowiedz

17

myślę, co chcesz tutaj jest związkiem nieważną i tablica:

{ 
    "type":"record", 
    "name":"test_avro", 
    "fields":[{ 
      "name":"test_field_1", 
      "type":"long" 
     }, 
     { 
      "name":"subrecord", 
      "type":[{ 
        "type":"record", 
        "name":"subrecord_type", 
        "fields":[{ 
          "name":"field_1", 
          "type":"long" 
         } 
        ] 
       }, 
       "null" 
      ] 
     }, 
     { 
      "name":"simple_array", 
      "type":["null", 
       { 
        "type":"array", 
        "items":"string" 
       } 
      ], 
      "default":null 
     } 
    ] 
} 

Kiedy użyć powyższego schematu z przykładowych danych w Pythonie, oto wynik (schema_string jest powyżej json string):

>>> from avro import io, datafile, schema 
>>> from json import dumps 
>>> 
>>> sample_data = {'test_field_1':12L} 
>>> rec_schema = schema.parse(schema_string) 
>>> rec_writer = io.DatumWriter(rec_schema) 
>>> rec_reader = io.DatumReader() 
>>> 
>>> # write avro file 
... df_writer = datafile.DataFileWriter(open("/tmp/foo", 'wb'), rec_writer, writers_schema=rec_schema) 
>>> df_writer.append(sample_data) 
>>> df_writer.close() 
>>> 
>>> # read avro file 
... df_reader = datafile.DataFileReader(open('/tmp/foo', 'rb'), rec_reader) 
>>> print dumps(df_reader.next()) 
{"simple_array": null, "test_field_1": 12, "subrecord": null} 
+0

Miałem ten sam problem z listami java, twoja odpowiedź rozwiązała mój problem. Dzięki! – forhas

+0

Otrzymuję ten sam błąd. W mojej instalacji próbuję przetworzyć plik Avro za pomocą programu MapReduce Java. Praca została pomyślnie zakończona. Kolejnym etapem linii danych jest utworzenie tabeli ula (avroSerde) nad przekształconymi danymi. Tabela również zostanie utworzona pomyślnie, ale gdy spróbuję wysłać zapytanie do tabeli za pomocą hql, (która z kolei wykonała zadanie Mapreduce), zadanie nie powiedzie się z "Błąd: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error podczas przetwarzania zapisu" – venBigData