我在尝试转换存储在Spark DataFrame中的原始时间字符串(hh:mm:ss)时遇到了一个问题,我使用了列类型为“string”的StructType。目标是将这些时间值写入目标列类型为“Time”的关系数据库。
val timeRegex = "(([0-1]?[0-9])|(2[0-3])):[0-5][0-9]:[0-5][0-9]"
var convertedData = newData
newData.schema.fields.foreach { field =>
val columnName = field.name
val dataType = field.dataType
if (dataType == StringType) {
convertedData = convertedData.withColumn(
columnName,
when(expr(s"col($columnName) rlike '$timeRegex'"),
to_utc_timestamp(substring(col(columnName), 1, 8), "HH:mm:ss").cast("timestamp").cast("time"))
.otherwise(col(columnName))
)
}
}
字符串
newData是包含我的数据的数据框,time列是hh:mm:ss格式的字符串。然而,当任何字符串(甚至是像“ABCDF_12345”这样的非时间字符串)与timeRegex匹配时就会出现问题。这会导致otherwise块尝试转换为时间戳,从而导致错误。
我正在寻求如何修改代码或改进正则表达式的建议,以确保只有有效的时间字符串被转换,其他字符串保持不变。当前的正则表达式似乎过于宽松,允许非时间字符串匹配。
任何在Spark SQL中实现这种转换的见解或替代方法都将受到极大的赞赏。
1条答案
按热度按时间qgzx9mmu1#
如果Postgres Time列可以接受Spark Timestamp,则带时间的String字段可以转换为Timestamp;无效时间将转换为null:
字符串
测试结果:
型
结果架构:
型