【问题标题】:Schema mismatch - Spark DataFrame written to Delta架构不匹配 - 写入 Delta 的 Spark DataFrame
【发布时间】:2020-06-03 08:56:40
【问题描述】:

将数据帧写入 delta 格式时,生成的 delta 似乎不遵循所写入数据帧的架构。具体来说,无论源数据帧模式如何,字段的“可为空”属性在生成的增量中似乎始终为“真”。这是预期的还是我在这里犯了错误?有没有办法让写入的 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))

【问题讨论】:

    标签: apache-spark apache-spark-sql delta-lake


    【解决方案1】:

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

    也许你写了一个 parquet,它肯定不为 null,但在 parquet 中写入时永远不会验证架构,并且任何人都可以使用相同的架构附加一些数据,但带有空值。因此,为了预防,spark 将始终将列设置为可为空。

    可以使用目录来防止这种行为,该目录将验证数据框是否遵循预期的架构。

    【讨论】:

    • 感谢您的回复。 3.0 之前的 Spark 版本总是放置可以为空的列 :(
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多