2017-04-25 67 views
2

我有一個CSV文件,test.csv不能以星火2.x到覆蓋一個CSV文件的架構

col 
1 
2 
3 
4 

當我使用的火花呢讀取,它得到數據的正確模式:

val df = spark.read.option("header", "true").option("inferSchema", "true").csv("test.csv") 

df.printSchema 
root 
|-- col: integer (nullable = true) 

但是,當我覆蓋CSV文件的schema並使inferSchema爲false時,則SparkSession正在部分提取自定義模式。

val df = spark.read.option("header", "true").option("inferSchema", "false").schema(StructType(List(StructField("custom", StringType, false)))).csv("test.csv") 

df.printSchema 
root 
|-- custom: string (nullable = true) 

我的意思是隻有列名(custom)和數據類型(StringType)越來越回升。但是,nullable部分被忽略,因爲它仍然是nullable = true,這是不正確的。

我無法理解此行爲。任何幫助表示讚賞!

+1

類似的帖子在http://stackoverflow.com/questions/41705602/spark-dataframe-schema-nullable-fields – abaghel

+0

它看起來相似!但是我能夠理解答案,爲什麼數據源可以支持可空性? – himanshuIIITian

回答

1

我相信「inferSchema」屬性是常見的,適用於數據框中的所有元素。但是,如果我們想改變一個特定元素的可空屬性。

我們可以處理/設置類似,

setNullableStateOfColumn(DF,「關口」,假)

​​3210

有一個類似的線程設置元素的可空屬性,

Change nullable property of column in spark dataframe

+0

感謝您的迴應!這個解決方案爲我工作。現在我可以根據我的'schema'設置可空屬性。儘管這個問題仍然是Spark 2.x中的一個錯誤,但它看起來像一個很好的解決方法。再次感謝! – himanshuIIITian

0

考慮從documentation關於Parquet(一種流行的「大數據」存儲格式)的摘錄:

Spark SQL提供對讀寫Parquet文件的支持,該文件可自動保留原始數據的模式。在編寫Parquet文件時,出於兼容性原因,所有列都會自動轉換爲空值。

CSV是出於同樣的原因相同的方式處理。

至於什麼‘兼容性原因’的意思,內森馬茲在他的書中大數據描述了一個理想的存儲架構是既強類型的完整和靈活的進化,換句話說,應該很容易添加和刪除字段,不會讓你的分析失敗Parquet既是類型化的,也是靈活的; CSV只是靈活的。你可以辯論你是否喜歡這種方法。

一個SQL表的模式嚴謹經過定義並且很難改變 - 太多了,Scott Ambler就如何重構它們寫了一個大的book。實木複合地板和CSV的要求不那麼嚴格。它們都適用於構建它們的範例,而Spark的方法是採取通常與「大數據」存儲格式相關的自由主義方法。

+1

據我所知,由於兼容性問題,默認情況下,nullable屬性設置爲「true」。但是,如果明確指定,修改它的靈活性應該可以工作。 – himanshuIIITian

+0

您發佈的問題和您的評論問題(「至於爲什麼數據源可以支持可空性?」)表示混淆了爲什麼您的顯式設置不起作用以及數據源與它有什麼關係。我回答了這個問題。你相信這是一個錯誤是客觀錯誤的;它是一個記錄,故意的功能。不要聲明任何你不喜歡的錯誤,而應考慮在討論區提出你的疑慮,並聽取反對意見或更好地提交拉請求。 – Vidya

+0

我已經在Spark Issue Tracker上報告了它的一個錯誤 - https://issues.apache.org/jira/browse/SPARK-20457。但不幸的是,它被標記爲'Duplicate':P – himanshuIIITian