![](/img/trans.png)
[英]Spark ClosedChannelException exception during parquet write
[英]Data format inconsistency during read/write parquet file with spark
這是我使用 spark/scala 從文件myfile.parquet
中讀取的輸入數據的架構:
val df = spark.read.format("parquet").load("/usr/sample/myIntialFile.parquet")
df.printSchema
root
|-- details: string (nullable = true)
|-- infos: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- text: string (nullable = true)
| | |-- id: string (nullable = true)
| | |-- value: string (nullable = true)
然后,我只是做了一個.select("infos")
並將數據框寫為 parquet 文件(假設為sparkProcessedFile.parquet
)。 當然, infos
列的數據模式保持不變。
另一方面,當我嘗試使用 pyarrow 比較myIntialFile.parquet
和sparkProcessedFile.parquet
的模式時,我沒有得到相同的數據模式:
import pyarrow.parquet as pa
initialTable = pa.read_table('myIntialFile.parquet')
initialTable.schema
infos: list<array: struct<text: string, id: string, value: string> not null>
sparkProcessedTable = pa.read_table('sparkProcessedFile.parquet')
sparkProcessedTable.schema
infos: list<element: struct<text: string, id: string, value: string>>
我不明白為什么會有區別( list<array<struct>>
而不是list<struct>
)以及為什么 spark 用簡單的選擇改變了初始嵌套結構。
感謝您的任何建議。
實際數據類型沒有改變。 在這兩種情況下, infos
都是可變大小的結構列表。 換句話說, infos
數組中的每一項都是結構列表。
可以說,名稱array
或element
沒有什么意義。 我認為不同的鑲木地板讀者/作家基本上只是在這里編造一些東西。 請注意,pyarrow 在從內存中創建新數組時會調用字段item
:
>>> pa.list_(pa.struct([pa.field('text', pa.string()), pa.field('id', pa.string()), pa.field('value', pa.string())]))
ListType(list<item: struct<text: string, id: string, value: string>>)
似乎 Spark 正在將“列表元素名稱”規范化為element
(或者可能是其架構中的任何內容),而不管 parquet 文件中實際存在什么。 這似乎是一件合理的事情(盡管可以想象它會導致兼容性問題)
也許更令人擔憂的是,字段items
從“非空”變為“可空”。 同樣,Spark 將該字段報告為“可為空”,因此 Spark 已決定所有數組列都可以為空,或者 Spark 已決定架構要求以其他方式可以為空。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.