架构不匹配 - 写入 Delta 的 Spark DataFrame

Schema mismatch - Spark DataFrame written to Delta

将数据帧写入增量格式时,生成的增量似乎不符合所写入数据帧的架构。具体来说,无论源数据帧模式如何,字段的 'nullable' 属性 在结果增量中似乎总是 'true' 。这是预期的还是我在这里犯了错误?有没有办法让写入的增量模式与源 df 完全匹配?

scala> df.schema
res2: org.apache.spark.sql.types.StructType = StructType(StructField(device_id,StringType,false), StructField(val1,StringType,true), StructField(val2,StringType,false), StructField(dt,StringType,true))

scala> df.write.format("delta").save("D:/temp/d1")

scala> spark.read.format("delta").load("D:/temp/d1").schema
res5: org.apache.spark.sql.types.StructType = StructType(StructField(device_id,StringType,true), StructField(val1,StringType,true), StructField(val2,StringType,true), StructField(dt,StringType,true))

delta lake底层格式parquet写法,不能保证列的可空性

也许您编写了一个 parquet 并确定它不为空,但模式在写入 parquet 时从未经过验证,并且任何人都可以附加一些具有相同模式但具有空值的数据。所以 spark 总是将列设置为可空的,只是为了预防。

可以使用目录来防止此行为,目录将验证数据框是否遵循预期的模式。

问题是很多用户认为他们的架构不可为空,并写入了空数据。然后他们无法读回数据,因为他们的镶木地板文件已损坏。为了避免这种情况,我们始终假设 table 模式在 Delta 中可以为空。在 Spark 3.0 中,在创建 table 时,您将能够将列指定为 NOT NULL。这样,Delta 将实际上阻止写入空值,因为 Delta 将在写入时检查列实际上不为空。