我之前已将Dataset[T]写入csv文件。
在本例中,T是一个case类,它包含字段x:Option[BigDecimal]
当我尝试将文件加载回Dataset[T]时,我看到以下错误:
Exception in thread "main" org.apache.spark.sql.AnalysisException: Cannot up cast `x` from double to decimal(38,18) as it may truncate.
我想原因是推断的模式包含一个double而不是BigDecimal列。有办法解决这个问题吗?我希望避免基于列名进行强制转换,因为读取代码是泛型函数的一部分。我的阅读代码如下:
val a = spark
.read
.format("com.databricks.spark.csv")
.option("header", "true")
.option("inferSchema", "true")
.load(file)
.as[T]
我的case类反映了从JDBC读取的表,其中Option[T]
用于表示可空字段。Option[BigDecimal]
用于从JDBC接收Decimal字段。
在本地机器上读写csv文件时,我已经编写了一些代码来读写csv文件,这样我就可以轻松地检查内容。
所以我的下一次尝试是:
var df = spark
.read
.format("com.databricks.spark.csv")
.option("header", "true")
.schema(implicitly[Encoder[T]].schema)
.load(file)
val schema = df.schema
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
schema.foreach{ field =>
field.dataType match {
case t: DoubleType =>
df = df.withColumn(field.name,
col(field.name).cast(DecimalType(38,18)))
case _ => // do nothing
}
}
df.as[T]
不幸的是,我的case类现在包含所有无
,而不是预期的值。如果我只是将csv加载为具有推断类型的DF,则所有列值都被正确填充。
看起来我实际上有两个问题。
如有任何帮助/建议,将不胜感激。如果很容易从csv文件中写入/读取选项/大小数有问题,我很乐意调整我的方法。
首先,我将用dfB填充空值。不适用。填充(0.0),然后我将尝试下一个解决方案:
case class MyCaseClass(id: String, cost: Option[BigDecimal])
var dfB = spark.createDataset(Seq(
("a", Option(12.45)),
("b", Option(null.asInstanceOf[Double])),
("c", Option(123.33)),
("d", Option(1.3444))
)).toDF("id", "cost")
dfB
.na.fill(0.0)
.withColumn("cost", col("cost").cast(DecimalType(38,18)))
.as[MyCaseClass]
.show()
首先将列cost显式转换为DecimalType(38,18),然后检索数据集[MyCaseClass]。我认为这里的问题是spark无法在没有明确指定缩放精度的情况下将double转换为BigDecimal,因此需要首先将其转换为特定的十进制类型,然后将其用作BigDecimal。
更新:我稍微修改了之前的代码,以便也可以处理Option[BigDecimal]类型的成员
祝你好运
问题内容: 在我的存储过程中,我通过了一个过滤器(使用“ WHERE Column IN”子句)作为参数。参数的值以CSV形式给出。将CSV转换为记录集的最佳方法是什么。 例子:- 我需要将名称作为参数传递给CSV字符串,例如 。 问题答案: 看看Erland Sommarskog的文章。他对做这种事情的不同方式有深入的了解: SQL Server中的数组和列表
我只是想说清楚,我的意思是这样的- 另外,如果我访问第一个数组以外的元素,也会遇到同样的问题,即(INT*)arr+13。它会属于越界访问的条款吗?因为我是在第一个数组的边界之外访问的。
主要内容:精确数字类型,数字类型,日期和时间类型,字符串,Unicode字符串,二进制字符串,T-SQL中使用的其他数据类型,T-SQL中流量控制的关键词SQL Server 中的数据类型是一个属性,它生成对象的数据。每个变量、列和表达式都与 T-SQL 中的数据类型相关。创建表时将根据需要为基于列的表选择特定的数据类型。 SQL Server 有七大类,包括多种数据类型。 精确数字类型 类型 最小值 最大值 Bigint -9,223,372,036,854,775,808 9,223,372
问题内容: 我正在尝试在子句中构建case / if语句。 问题在于该列包含文本和数字。我要与之比较的列是一个整数。 有没有一种方法可以检测列是否包含字符或数字,然后将其设置为0,然后将其设置为0? 这是一个伪查询可以帮助您: 问题答案: 您正在寻找IsNumeric,但它并不总是有效(+,-和。是数字),因此您需要使用GBN所描述的解决方案,即在您的varchar中添加.0e0
基本上,我想读取Apache Ignite上的查询返回的所有值,该查询返回一个IgniteCursor。 我想以非阻塞的方式读取光标。 我可以写: 也许我错过了什么? 换句话说,有一种方法可以使用“异步非阻塞IO”从Ignite获取记录列表?
我使用的是Azure.data.tables nuget包的12.0.0-beta.6。当我尝试调用TableClient.GetQueryAsync时,它会给出错误: “类型”T“必须是引用类型,才能将其用作泛型类型或方法”TableClient.GetEntityAsync(string,string,IEnumerable,CancellationToken)“中的参数”T“。” 我看不出我