如何让 Spark SQL 导入没有“L”后缀的 Long?

Posted

技术标签:

【中文标题】如何让 Spark SQL 导入没有“L”后缀的 Long?【英文标题】:How can I get Spark SQL to import a Long without an "L" suffix? 【发布时间】:2016-06-17 19:50:45 【问题描述】:

我有一组通过 Sqoop 生成 mysql 数据库的 CSV。我正在尝试将它们定义为 Spark 中数据框的来源。

源数据库中的模式包含多个具有 Long 数据类型的字段,并且实际上在这些字段中存储了巨大的数字。

当尝试访问数据帧时,Scala 无法解释这些,因为我在长整数上没有 L 后缀。

例如,这会引发错误:val test: Long = 20130102180600

虽然成功:val test: Long = 20130102180600L

有没有办法强制 Scala 将这些解释为没有后缀的长整数?由于数据的规模,我认为在字段来自数据库时对其进行后处理是不可行的。

【问题讨论】:

我改了标题,因为“Scala”在这里没有导入任何东西,它是一个特定的库。 【参考方案1】:

明确给出架构,如 README 中的示例:

import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.types.StructType, StructField, StringType, IntegerType

val sqlContext = new SQLContext(sc)
val customSchema = StructType(Array(
    StructField("year", IntegerType, true),
    StructField("make", StringType, true),
    StructField("model", StringType, true),
    StructField("comment", StringType, true),
    StructField("blank", StringType, true)))

val df = sqlContext.load(
    "com.databricks.spark.csv",
    schema = customSchema,
    Map("path" -> "cars.csv", "header" -> "true"))

val selectedData = df.select("year", "model")
selectedData.save("newcars.csv", "com.databricks.spark.csv")

当然,对于大整数字段使用LongType 除外。

查看代码,这绝对看起来应该可以工作:字段是converted from String to desired type using TypeCast.castToTypeCast.castToLongType just calls datum.toLong,可以按需要工作(您可以在 Scala REPL 中查看"20130102180600".toLong)。事实上,InferSchema 也处理这种情况。我强烈怀疑问题有所不同:也许这些数字甚至超出了Long 的范围?

(我实际上还没有尝试过,但我希望它可以工作;如果没有,您应该报告错误。从阅读https://***.com/help/mcve开始。)

【讨论】:

是的,这正是我们正在做的,为了简单起见,我缩写了。您认为这是 Scala 还是 databricks CSV 库的错误? 当然是在 CSV 库中。它可能是由 Scala 中的错误引起的,但没有理由假设它是。

以上是关于如何让 Spark SQL 导入没有“L”后缀的 Long?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免Spark SQL做数据导入时产生大量小文件

idea运行spark无法导入sql包object sql is not a member of package org.apache.spark

后缀为sql的文件 用记事本、文档打开显示是乱码,求老手指点指点,用啥才能打开呢?mysql 可以看吗?

如何使用 Spark SQL 对均值列进行排序?

如何将sql文件导入postgres

我们可以使用 spark-sql 或 apache spark 运行 sqoop 导入语句吗