В следующем коде я создал Dataset<Person>
и хочу записать это в файл Avro.Из-за класса Person, использующего ZonedDateTime
Spark 2.1.0, не примет меня, используя Encoders.bean(Person.class)
(т.е. NullPointerExceptions), поэтому я использовал Encoders.kryo(Person.class)
.
При вызове ds.printSchema()
я вижу, чтоНабор данных содержит одно поле с моим закодированным объектом Person.
При вызове ds.write()
я ожидал, что десериализация будет работать бесплатно, и я увидел бы схему Avro, содержащую поля Person name
и lastUpdated
.К сожалению, это всего лишь одно двоичное поле снова.
public class Person
{
private String name;
private ZonedDateTime lastUpdated;
// constructor + getters/setters omitted
}
public class MyTest
{
private SparkContext sc;
@Before
public void setUp()
{
sc = new SparkContext(new SparkConf()
.setMaster("local[2]")
.setAppName("test"));
}
@Test
public void test()
{
final Person bob = new Person("Bob", ZonedDateTime.now());
Dataset<Person> ds = SparkSession.builder().sparkContext(sc).getOrCreate().sqlContext().createDataset(Arrays.asList(bob), Encoders.kryo(Person.class));
System.out.println(ds.first());
// com.db.rca.ts.fd.spark.Person@20d87335[name=Bob,lastUpdated=2018-10-01T19:23:18.742null[Europe/London]]
ds.printSchema();
// root
// |-- value: binary (nullable = true)
ds.write()
.mode(SaveMode.Overwrite)
.format("com.databricks.spark.avro")
.save("./target/output");
// avro file output contains the one binary field?
}
}
Я удалил бизнес-логику из моего примера, чтобы предоставить рабочий код.Как правильно загрузить данные в безопасный для типов набор данных, а затем записать его так, чтобы все поля класса Person были видны в схеме Avro?
Я вернусь к использованию JavaRDD
APIесли API Dataset
еще не продвинулись.