验证 parquet 文件中的 NULL 值
Posted
技术标签:
【中文标题】验证 parquet 文件中的 NULL 值【英文标题】:Validate NULL values from parquet files 【发布时间】:2020-09-25 10:48:03 【问题描述】:我正在从第三方读取镶木地板文件。似乎 parquet 总是将文件的架构转换为可为空的列,无论它们是如何编写的。
读取这些文件时,我想拒绝在特定列中包含 NULL 值的文件。使用 csv 或 json 你可以:
schema = StructType([StructField("id", IntegerType(), False), StructField("col1", IntegerType(), False)])
df = spark.read.format("csv").schema(schema).option("mode", "FAILFAST").load(myPath)
如果负载在col1
中包含NULL,则会被拒绝。如果您在 Parquet 中尝试这样做,它将被接受。
我可以对 Null 值的列进行过滤或计数并引发错误 - 从性能立场来看,这很糟糕,因为我将在工作中获得额外的阶段。它还将拒绝完整的数据帧和所有文件(是的,CSV 路由也这样做)。
是否对读取的文件强制执行验证?
如果有帮助,我正在使用版本 Spark 3。
用例子编辑:
from pyspark.sql.types import *
schema = StructType([
StructField("Id", IntegerType(), False),
StructField("col1", IntegerType(), True)
])
df = spark.createDataFrame([(1,1),(2, None)], schema)
df.write.format("parquet").mode("overwrite").save("/tmp/parquetValidation/")
df2 = spark.read.format("parquet").load("/tmp/parquetValidation/")
df2.printSchema()
返回
|-- Id: integer (nullable = true)
|-- col1: integer (nullable = true)
使用阻止空值的架构重新读取文件:
schema = StructType([
StructField("Id", IntegerType(), False),
StructField("col1", IntegerType(), False)
])
df3 = spark.read.format("parquet").schema(schema).option("mode", "FAILFAST").load("/tmp/parquetValidation/")
df3.printSchema()
返回:
|-- Id: integer (nullable = true)
|-- col1: integer (nullable = true)
即未应用架构。
【问题讨论】:
这可以帮助您理解问题。 github.com/apache/spark/pull/17293 .. 甚至还有一种解决方法 【参考方案1】:感谢 cmets 中的@Sasa 提出问题。
from pyspark.sql import DataFrame
schema = StructType([
StructField("Id", IntegerType(), False),
StructField("col1", IntegerType(), False)
])
df_junk = spark.read.format("parquet").schema(schema).load("/tmp/parquetValidation/")
new_java_schema = spark._jvm.org.apache.spark.sql.types.DataType.fromJson(schema.json())
java_rdd = df_junk._jdf.toJavaRDD()
new_jdf = spark._jsparkSession.createDataFrame(java_rdd, new_java_schema)
df_validate = DataFrame(new_jdf, df.sql_ctx)
df_validate.printSchema()
返回
|-- Id: integer (nullable = false)
|-- col1: integer (nullable = false)
运行一个动作会导致:
java.lang.RuntimeException: The 1th field 'col1' of input row cannot be null.
放到 java rdd 上不太好 - 但它可以工作
【讨论】:
以上是关于验证 parquet 文件中的 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章
使用Spark读写Parquet文件验证Parquet自带表头的性质及NULL值来源Java
使用Spark读写Parquet文件验证Parquet自带表头的性质及NULL值来源Java
BigQuery 加载镶木地板错误 - Parquet 中的字段 INT32 与架构中的 double 类型不兼容