2016-03-06 80 views
3

我似乎無法寫實木複合地板JavaRDD<T>,其中T是說,Person類。我把它定義爲Spark SQL:鑲嵌類實木複合地板錯誤

public class Person implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 
    private String name; 
    private String age; 
    private Address address; 
.... 

Address

public class Address implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 
    private String City; private String Block; 
    ...<getters and setters> 

我然後創建一個JavaRDD像這樣:

JavaRDD<Person> people = sc.textFile("/user/johndoe/spark/data/people.txt").map(new Function<String, Person>() 
    { 
     public Person call(String line) 
     { 
      String[] parts = line.split(","); 
      Person person = new Person(); 
      person.setName(parts[0]); 
      person.setAge("2"); 
      Address address = new Address("HomeAdd","141H"); 
      person.setAddress(address); 
      return person; 
     } 
    }); 

注 - 我手動設置Address同所有。這基本上是一個嵌套的RDD。在試圖將此保存爲文件拼花:

DataFrame dfschemaPeople = sqlContext.createDataFrame(people, Person.class); 
dfschemaPeople.write().parquet("/user/johndoe/spark/data/out/people.parquet");  

地址類:

import java.io.Serializable; 
public class Address implements Serializable 
{ 
    public Address(String city, String block) 
    { 
     super(); 
     City = city; 
     Block = block; 
    } 
    private static final long serialVersionUID = 1L; 
    private String City; 
    private String Block; 
    //Omitting getters and setters 
} 

我遇到的錯誤:

造成的:java.lang.ClassCastException:com.test .schema.Address無法轉換爲org.apache.spark.sql.Row

我正在運行spark-1.4.1。

  • 這是一個已知的錯誤嗎?
  • 如果我通過導入相同格式的嵌套JSON文件來做同樣的事情,我可以保存到實木複合地板。
  • 即使我創建一個子數據幀,如:DataFrame dfSubset = sqlContext.sql("SELECT address.city FROM PersonTable");我仍然得到同樣的錯誤

那麼是什麼原因?如何從文本文件中讀取複雜的數據結構並將其保存爲拼花地板?似乎我做不到。

+1

我這樣做,並沒有問題。它輸出到標準輸出:'System.out.println(dfschemaPeople.count());'這是當保存到實木複合地板時,我得到這個錯誤。請注意,如果我有JSON數據,我可以寫入實木複合地板,只有我不能使用的類對象。 – Dan

回答

3

您正在使用具有侷限性

從火花文檔的Java API: http://spark.apache.org/docs/1.4.1/sql-programming-guide.html#interoperating-with-rdds

火花SQL支持自動轉換的JavaBeans的RDD成數據幀。使用反射獲得的BeanInfo定義表的模式。目前,Spark SQL不支持包含嵌套或包含複雜類型(例如Lists或Arrays)的JavaBean。您可以通過創建一個實現Serializable的類來創建JavaBean,併爲其所有字段設置getter和setter。 使用Scala case類會工作(更新寫入拼花格式)

import org.apache.spark.SparkContext 
import org.apache.spark.SparkContext._ 
import org.apache.spark.SparkConf 
import org.apache.spark.rdd.RDD 

case class Address(city:String, block:String); 
case class Person(name:String,age:String, address:Address); 
object Test2 { 
    def main(args: Array[String]): Unit = { 

    val conf = new SparkConf().setAppName("Simple Application").setMaster("local"); 
     val sc = new SparkContext(conf) 
     val sqlContext = new org.apache.spark.sql.SQLContext(sc); 
     import sqlContext.implicits._ 
     val people = sc.parallelize(List(Person("a", "b", Address("a", "b")), Person("c", "d", Address("c", "d")))); 

     val df = sqlContext.createDataFrame(people); 
     df.write.mode("overwrite").parquet("/tmp/people.parquet") 
    } 
} 
+0

謝謝!我不知何故錯過了該頁面上的那一行。所以這是一個限制。我確實發現了一個黑客。如果複雜對象轉換爲JSON並將JSON轉換爲DataFrame,那麼我可以將其保存爲實木複合地板。 Java Bean不起作用,但是JSON可以! – Dan

+0

它很容易錯過,因爲它出現在java標籤中...我有同樣的問題 –

相關問題