искра преобразовать строку в TimestampType - PullRequest
0 голосов
/ 02 мая 2018

У меня есть фрейм данных, который я хочу вставить в Postgresql в спарк. В искре столбец DateTimestamp имеет строковый формат. В postgreSQL это TimeStamp без часового пояса.

Исключаются ошибки при вставке в базу данных по столбцу даты и времени. Я попытался изменить тип данных, но вставка все еще выдает ошибки. Я не могу понять, почему приведение не работает. Если я вставляю ту же строку вставки в PgAdmin и запускаю, оператор вставки работает нормально.

import java.text.SimpleDateFormat;
import java.util.Calendar
object EtlHelper {
 // Return the current time stamp

  def getCurrentTime() : String = {    
    val now = Calendar.getInstance().getTime()   
    val hourFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")   
    return hourFormat.format(now)   
  }
 }  

В другом файле

object CreateDimensions {

def createDimCompany(spark:SparkSession, location:String, propsLocation :String):Unit = {      
import spark.implicits._    

val dimCompanyStartTime = EtlHelper.getCurrentTime()
val dimcompanyEndTime = EtlHelper.getCurrentTime()
val prevDimCompanyId = 2
val numRdd = 27
val AuditDF = spark.createDataset(Array(("dim_company", prevDimCompanyId,numRdd,dimCompanyStartTime,dimcompanyEndTime))).toDF("audit_tbl_name","audit_tbl_id","audit_no_rows","audit_tbl_start_date","audit_tbl_end_date")//.show()

AuditDF.withColumn("audit_tbl_start_date",AuditDF.col("audit_tbl_start_date").cast(DataTypes.TimestampType))
AuditDF.withColumn("audit_tbl_end_date",AuditDF.col("audit_tbl_end_date").cast(DataTypes.TimestampType))

AuditDF.printSchema()
}  
}

root
 |-- audit_tbl_name: string (nullable = true)
 |-- audit_tbl_id: long (nullable = false)
 |-- audit_no_rows: long (nullable = false)
 |-- audit_tbl_start_date: string (nullable = true)
 |-- audit_tbl_end_date: string (nullable = true)

Это ошибка, которую я получаю

INSERT INTO etl.audit_master ("audit_tbl_name","audit_tbl_id","audit_no_rows","audit_tbl_start_date","audit_tbl_end_date") VALUES ('dim_company',27,2,'2018-05-02 12:15:54','2018-05-02 12:15:59') was aborted: ERROR: column "audit_tbl_start_date" is of type timestamp without time zone but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

Любая помощь приветствуется.

Спасибо

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Корень вашей проблемы в том, что упомянул @Ramesh, т. Е. Что вы не присваивали изменения в AuditDF новому значению (val), отметьте, что и фрейм данных, и значение, которому вы его присвоили, являются неизменяемыми (т. Е. AuditDF был определил val, поэтому его также нельзя изменить)

Другое дело, что вам не нужно заново изобретать колесо и использовать искру EtlHelper со встроенной функцией, которая дает вам метку времени текущего времени:

import org.apache.spark.sql.functions._

val AuditDF = spark.createDataset(Array(("dim_company", prevDimCompanyId,numRdd)))
.toDF("audit_tbl_name","audit_tbl_id","audit_no_rows")
.withColumn("audit_tbl_start_date"current_timestamp())
.withColumn("audit_tbl_end_date",current_timestamp())
0 голосов
/ 03 мая 2018

AuditDF.printSchema() принимает исходный кадр данных AuditDF, поскольку вы не сохранили преобразования .withColumn с помощью присваивания. Фреймы данных - это неизменяемые объекты, которые могут быть преобразованы в другие фреймы данных, но не могут изменить себя. Таким образом, вам всегда потребуется назначение для сохранения примененных преобразований.

поэтому правильный способ - присвоить, чтобы сохранить изменения

val transformedDF = AuditDF.withColumn("audit_tbl_start_date",AuditDF.col("audit_tbl_start_date").cast(DataTypes.TimestampType))
                          .withColumn("audit_tbl_end_date",AuditDF.col("audit_tbl_end_date").cast("timestamp"))

transformedDF.printSchema()

вы увидите изменения

root
 |-- audit_tbl_name: string (nullable = true)
 |-- audit_tbl_id: integer (nullable = false)
 |-- audit_no_rows: integer (nullable = false)
 |-- audit_tbl_start_date: timestamp (nullable = true)
 |-- audit_tbl_end_date: timestamp (nullable = true)

.cast(DataTypes.TimestampType) и .cast("timestamp") одинаковы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...