sparkDataframe写入增量

gblwokeq  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(501)

将Dataframe写入delta格式时,生成的delta似乎不遵循所写入的Dataframe的模式。具体来说,不管源Dataframe模式如何,字段的“nullable”属性在结果增量中似乎总是“true”。这是预期的还是我在这里犯了错误?有没有办法让写入的delta的模式与源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))
gfttwv5a

gfttwv5a1#

在delta lake的底层格式parquet中写入不能保证列的可空性。
也许您编写了一个parquet,它肯定不是空的,但是在write-in-parquet上从来没有验证过这个模式,任何人都可以使用相同的模式附加一些数据,但是使用空值。所以spark总是把列设为null,只是为了预防。
可以使用目录防止这种行为,目录将验证Dataframe是否遵循预期的模式。

lstz6jyr

lstz6jyr2#

问题是,许多用户认为他们的模式不可为空,于是编写了空数据。然后他们无法读取数据回来,因为他们的Parquet地板文件已损坏。为了避免这种情况,我们总是假设表模式在delta中可以为null。在spark 3.0中,创建表时,可以将列指定为NOTNULL。这样,delta实际上会阻止空值被写入,因为delta在写入列时会检查列是否不是空的。

相关问题