【问题标题】:VarcharType mismatch Spark dataframeVarcharType 不匹配 Spark 数据帧
【发布时间】:2020-01-23 22:54:36
【问题描述】:

我正在尝试更改数据框的架构。每次我有一列字符串类型时,我都想将其类型更改为 VarcharType(max),其中 max 是该列中字符串的最大长度。我写了以下代码。 (我想稍后将数据帧导出到 sql server,我不想在 sql server 中有 nvarchar,所以我试图在 spark 端限制它)

val df = spark.sql(s"SELECT * FROM $tableName")

var l : List [StructField] = List()

val schema = df.schema
schema.fields.foreach(x => {

  if (x.dataType == StringType) {
    val dataColName = x.name
    val maxLength = df.select(dataColName).reduce((x, y) => {
      if (x.getString(0).length >= y.getString(0).length) {
        x
      } else {
        y
      }
    }).getString(0).length

    val dataType = VarcharType(maxLength)
    l = l :+ StructField(dataColName, dataType)
  } else {
    l = l :+ x
  }
})

val newSchema = StructType(l)
val newDf = spark.createDataFrame(df.rdd, newSchema)

但是在运行它时我得到了这个错误。

  20/01/22 15:29:44 ERROR ApplicationMaster: User class threw exception: scala.MatchError: 
  VarcharType(9) (of class org.apache.spark.sql.types.VarcharType)
  scala.MatchError: VarcharType(9) (of class org.apache.spark.sql.types.VarcharType)

数据框列可以是 VarcharType(n) 类型吗?

【问题讨论】:

  • 你能用StringType映射到sqlserver上的varchar列吗
  • 问题是我想限制字符串长度。我可以用 StringType 做到这一点吗?
  • StringType 映射到 NVARCHAR(MAX)。我想你可以修改它。我会回答的。

标签: dataframe apache-spark varchar


【解决方案1】:

从数据库到/从数据帧的数据映射发生在方言类中。对于 MS SQL 服务器,该类是 org.apache.spark.sql.jdbc.MsSqlServerDialect。您可以继承并覆盖 getJDBCType 以影响从数据框到表的数据类型映射。然后注册您的方言使其生效。

我已经为 Oracle(不是 sqlserver)做了这个,但是它可以类似地完成。

//Change this
  override def getJDBCType(dt: DataType): Option[JdbcType] = dt match {
    case TimestampType => Some(JdbcType("DATETIME", java.sql.Types.TIMESTAMP))
    case StringType => Some(JdbcType("NVARCHAR(MAX)", java.sql.Types.NVARCHAR))
    case BooleanType => Some(JdbcType("BIT", java.sql.Types.BIT))
    case _ => None
  }

您不能使用 VarcharType,因为它不是 DataType。此外,您无法检查实际数据的长度,因为它没有公开。您只能访问“dt: DataType”,因此如果 max 不可接受,您可以为 NVARCHAR 设置默认大小。

【讨论】:

    猜你喜欢
    • 2019-05-26
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多