INSERT如果不在Spark SQL

时间:2017-08-15 20:15:25

标签: apache-spark apache-spark-sql

是否有任何规定在Spark SQL中执行“INSERT IF NOT NOT EXISTS ELSE UPDATE”。

我有Spark SQL表“ABC”,它有一些记录。 然后我有另一批记录,我希望在此表中插入/更新它们是否存在于此表中。

是否有可以在SQL查询中使用的SQL命令来实现这一目标?

3 个答案:

答案 0 :(得分:3)

在常规Spark中,可以使用join后跟map来实现这一点:

import spark.implicits._
val df1 = spark.sparkContext.parallelize(List(("id1", "orginal"), ("id2", "original"))).toDF("df1_id", "df1_status")
val df2 = spark.sparkContext.parallelize(List(("id1", "new"), ("id3","new"))).toDF("df2_id", "df2_status")

val df3 = df1
  .join(df2, 'df1_id === 'df2_id, "outer")
  .map(row => {
    if (row.isNullAt(2))
      (row.getString(0), row.getString(1))
    else
      (row.getString(2), row.getString(3))
  })

这会产生:

scala> df3.show
+---+--------+
| _1|      _2|
+---+--------+
|id3|     new| 
|id1|     new|
|id2|original|
+---+--------+

你也可以select使用udfs代替map,但在这种特殊情况下使用空值,我个人更喜欢map变体。

答案 1 :(得分:0)

我知道共享我的代码有点晚了,但是为了添加或更新数据库,我做了一个如下所示的功能:

import pandas as pd

#Returns a spark dataframe with added and updated datas
#key parameter is the primary key of the dataframes
#The two parameters dfToUpdate and dfToAddAndUpdate are spark dataframes
def AddOrUpdateDf(dfToUpdate,dfToAddAndUpdate,key):
    #Cast the spark dataframe dfToUpdate to pandas dataframe
    dfToUpdatePandas = dfToUpdate.toPandas()

    #Cast the spark dataframe dfToAddAndUpdate to pandas dataframe
    dfToAddAndUpdatePandas = dfToAddAndUpdate.toPandas()

    #Update the table records with the latest records, and adding new records if there are new records.
    AddOrUpdatePandasDf = pd.concat([dfToUpdatePandas,dfToAddAndUpdatePandas]).drop_duplicates([key], keep = 'last').sort_values(key)

    #Cast back to get a spark dataframe
    AddOrUpdateDf = spark.createDataFrame(AddOrUpdatePandasDf)

    return AddOrUpdateDf

如您所见,我们需要将spark数据帧转换为pandas数据帧,以便能够执行pd.concat,尤其是drop_duplicates使用“ keep ='last'”,然后将其转换回spark数据帧并返回它。 我认为这不是处理AddOrUpdate的最佳方法,但至少可以奏效。

答案 2 :(得分:0)

你可以像这样使用spark sql:

select * from (select c.*, row_number() over (partition by tac  order by tag desc) as 
    TAG_NUM from (
    select 
         a.tac
        ,a.name
        ,0 as tag
    from tableA a
    union all
    select 
        b.tac
        ,b.name
         ,1 as tag
    from tableB b) c ) d where TAG_NUM=1

tac 是您要插入/更新的列。