Scala 如果dataframe列中的值为NULL,如何使用if-else语句抛出错误?

Scala 如果dataframe列中的值为NULL,如何使用if-else语句抛出错误?,scala,dataframe,apache-spark,user-defined-functions,Scala,Dataframe,Apache Spark,User Defined Functions,我将csv文件作为DF读取,其中最后3个必填列包含空值 有谁能告诉我如何在scala spark中的UDF中使用if-else语句,如果这些列中有空值,它会抛出一个错误,声明“必填字段不能为空”?我已经用scala spark编写了代码,因此如果我在其中得到任何建议,这将非常有用 这是我的第一个代码,请原谅我的错误。从下面的代码中,请指导我如何获取详细信息,如果任何if条件不满足,作业将失败,日志将被捕获,并带有ELSE语句中给出的错误消息,如果条件满足,则应将结果DF插入数据库。请分享您的建议

我将csv文件作为DF读取,其中最后3个必填列包含空值

有谁能告诉我如何在scala spark中的UDF中使用if-else语句,如果这些列中有空值,它会抛出一个错误,声明“必填字段不能为空”?我已经用scala spark编写了代码,因此如果我在其中得到任何建议,这将非常有用

这是我的第一个代码,请原谅我的错误。从下面的代码中,请指导我如何获取详细信息,如果任何if条件不满足,作业将失败,日志将被捕获,并带有ELSE语句中给出的错误消息,如果条件满足,则应将结果DF插入数据库。请分享您的建议:

import java.util.Date
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.functions._


object InputValidation {

  val conf: SparkConf = new SparkConf()
    .setAppName("Excel to DataFrame")
    .setMaster("local[*]")

  val sc = new SparkContext(conf)
  sc.setLogLevel("WARN")

  val spark: SparkSession = SparkSession.builder()
    .appName("Excel to DataFrame")
    .config("spark.master", "local")
    .getOrCreate()




 val structType: StructType = {
    val sno = StructField("S.No", IntegerType, nullable = true)
    val fname = StructField("Firm Name", StringType, nullable = true)
    val address = StructField("Address", StringType, nullable = true)
    val country = StructField("Country", StringType, nullable = true)
    val pcode = StructField("Post Code", IntegerType, nullable = true)
    val tnumber = StructField("Telephone Number", IntegerType, nullable = true)
    val waddress = StructField("Web Address", StringType, nullable = true)
    val mail = StructField("Mail ID", StringType, nullable = true)
    val fstatus = StructField("Firm Status", StringType, nullable = false)
    val btype = StructField("Business Type", StringType, nullable = false)
    val edate = StructField("Effective Date", DateType, nullable = false)
    new StructType(Array(sno, fname, address, country, pcode, tnumber, waddress, mail,
      fstatus, btype, edate))
  }
  def main(args: Array[String]): Unit = {
  val inputDF: DataFrame = spark.read
      .schema(structType)
      .option("header", "true")
      .option("delimiter", ",")
      .csv("G:\\CSV\\FirmRegistration.csv")


def isValidUDF: Object = udf({
  (fstatus: String, btype: String, edate: Date) => {
    val validfs = Seq("New", "Authorised", "EEA Authorised", "Cancelled")
    if (validfs.contains(fstatus)) {
      return fstatus
    }
    else {
      throw new Exception("Incorrect firm status")
    }

    val validbt = Seq("Regulated", "PSD", "EEA")
    if (validbt.contains(btype)) {
      return btype
    }
    else {
      throw new Exception("Incorrect firm business type")
    }

    if (edate != null) {
      return edate
    }
    else {
      throw new Exception("Effective date cannot be NULL")
    }
  }
})

  val userDF = udf(isValidUDF _)
  val resultDF = inputDF.withColumn("IsValid", userDF())
  resultDF.show()

//Load the result as a table into Database
    val driver = "org.postgresql.Driver"
    val url = "jdbc:postgressql://localhost:5432/rtjvm"
    val user = "docker"
    val password = "docker"

    inputDF.write
      .format("jdbc")
      .option("driver",driver)
      .option("url",url)
      .option("user",user)
      .option("password",password)
      .option("dbtable","public.input")
      .save()
}

}

如果我运行上面的程序,我会得到错误:线程“main”java.lang.UnsupportedOperationException中的异常:不支持类型对象的架构

def checkNullUDF = udf({
  (firmStatus: String, businessType: String, effectiveDate: String) => {
    if(firmStatus == null || businessType == null || effectiveDate == null) true else false
  }
})

df.withColumn("IsNull", checkNullUDF($"Firm Status", $"Business Type", $"Effective Date")

这将为您提供一个列“IsNull”,其中包含真/假值,您可以使用它来相应地引发异常。

如果不是df['col1','col2','col3']]。notna().all():#raiseexception
尽管更好,但您的数据库应该具有必要的约束,以确保不会插入错误数据。谢谢,ashishyadav。我现在已经在这篇文章中添加了我的代码。您能否告知如何在该代码中实现请求的条件?您确定您的条件是否正确吗?它不应该是“validfs.contains(fstatus)”,而应该是“validfs.contains(fstatus)”,并且与下一个if条件相同。无论如何,如果您只是想让代码在else块中失败,可以在那里抛出异常。类似这样:if(validfs.contains(fstatus)){return fstatus}else{throw new Exception(“错误的公司状态”)}再次感谢您,Ashish。刚刚注意到我把args放错了IF条件。现在我添加了一个例外。我做了更正并运行了代码,但是我得到了错误,因为在inputDF.withColumn(“IsValid”,isValidUDF($“Firm Status”,$“Business Type”,$“Effective Date”))行中的“isValidUDF不接受参数”。您好,如果您有任何其他建议,请与我们分享,不要再次注册为udf,因为在顶部定义isValidUDF时,您已经将其注册为udf。删除以下代码行val userDF=udf(isValidUDF uu)val resultDF=inputDF.withColumn(“IsValid”,userDF()),而只使用:inputDF.withColumn(“IsValid”,isValidUDF($“公司状态”,“$”业务类型“,$“生效日期”))