Значение Spark SQL named_struct как NULL - PullRequest
0 голосов
/ 15 февраля 2019

Я хочу обнулить какое-то значение в моем вложенном фрейме данных и записать его в Amazon Redshift, но я получаю java.lang.NullPointerException

Здесь больше контекста о моем сценарии использования и о том, что я сделал до сих пор.

Я использую spark-redshift (к сожалению, DataBrick решил сделать его закрытым), чтобы записать свой фрейм данных в красную рубашку

var writer = df
      .coalesce(numPartitions)
      .write
      .format("com.databricks.spark.redshift")
      .option("forward_spark_s3_credentials", true)
      .option("url", url)
      .option("dbtable", destTableName)
      .option("tempdir", s3tempDir)
      .option("postactions", s"grant select on table ${destTableName} to readonly")
      .mode(SaveMode.Append)

И я использую selectExpr для nullify тех значений, которыеЯ хочу в своей вложенной схеме

val sourceDFNull = sourceDF.selectExpr(
      """
      named_struct(
          'event_id', event_id,              
          'user', named_struct(
            'country', user.country,
            'id', user.id,
            'state', named_struct('level', null, 'xp', user.state.xp)
          )
      ) as named_struct
    """).select("named_struct.*")

И схема таблицы:

create table mySchema.myTable
(      
  event_id                                       varchar(256),
  country                                        varchar(256),
  user_id                                        varchar(256),
  level                                          double precision,
  xp                                             bigint
);  

Так что мой код Spark в основном применяет некоторую логику к вложенной схеме, генерирует фрейм данных и записывает егов красную рубашку.

Вот последний кадр данных перед записью в красное смещение

+---------------------+----------------+----------+--------+-------+
|       event_id      |     country    |  user_id |  level |  xp   |
+---------------------+----------------+----------+--------+-------+
| 54d69802-c414-4ab4  |      GB        |   123    |  null  |  12   |
+---------------------+----------------+----------+--------+-------+

Но как только я пытаюсь записать этот кадр данных, я получил исключение нулевого указателя

Я попытался вставить эту запись вручную в красную рубашку, и она работала нормально.

INSERT into mySchema.myTable(event_id,country,user_id,level,xp) values ('54d69802-c414-4ab4', 'GB', 123, null, 12);

Сказав, что моя таблица принимает значение null для уровня, и если я печатаю схему своего фрейма данных перед записью вкрасное смещение Iя получу это, которое показывает, что оно также принимает ноль:

 root
 |-- event_id: string (nullable = true)  
 |-- country: string (nullable = true)
 |-- user_id: string (nullable = true) 
 |-- level: null (nullable = true)
 |-- xp: null (nullable = true)

Единственное, что я подозреваю, это способ, которым я установил ноль в selectExpr, который named_struct('level', null, 'xp', user.state.xp)!

Если я опущу столбец

val result = resulttmp.drop("level")

и попытаюсь записать фрейм данных в красную рубашку, в которой он будет храниться null.но я не хочу опускать столбец.

Есть предложения о том, как это исправить?

...