![](/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.