Как вставить фрейм данных с массивом столбцов в Postgresql? - PullRequest
2 голосов
/ 09 мая 2020

Я пытаюсь сохранить фрейм данных с вложенной схемой в Postgresql. Может ли кто-нибудь помочь мне и объяснить, как хранить столбцы (координаты) и (user_mentions) в Postgres? Я читал, что postgres может хранить тип массива, но я получаю сообщение об ошибке при попытке записи в БД. Я не совсем уверен, правильно ли создана моя таблица.

Ошибка:

Exception in thread "main" java.lang.IllegalArgumentException: Can't get JDBC type for array<array<double>>

Схема DataFrame:

root
 |-- created_at: string (nullable = true)
 |-- id: long (nullable = true)
 |-- text: string (nullable = true)
 |-- source: string (nullable = true)
 |-- user_id: long (nullable = true)
 |-- in_reply_to_status_id: string (nullable = true)
 |-- in_reply_to_user_id: long (nullable = true)
 |-- lang: string (nullable = true)
 |-- retweet_count: long (nullable = true)
 |-- reply_count: long (nullable = true)
 |-- coordinates: array (nullable = true)
 |    |-- element: array (containsNull = true)
 |    |    |-- element: double (containsNull = true)
 |-- hashtags: array (nullable = true)
 |    |-- element: string (containsNull = true)
 |-- user_mentions: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- id: long (nullable = true)
 |    |    |-- id_str: string (nullable = true)
 |    |    |-- indices: array (nullable = true)
 |    |    |    |-- element: long (containsNull = true)
 |    |    |-- name: string (nullable = true)
 |    |    |-- screen_name: string (nullable = true)

Postgres Создание таблицы:

create table test-table (created_at varchar, id int, text text, source text, user_id int, in_reply_to_status_id varchar, in_reply_to_user_id int, lang varchar, retweet_count int, reply_count int, coordinates double precision[][], hashtags text[], user_mentions text[]);

Spark Scala Код:

   val df_1 = df.select(col("created_at"), col("id"), col("text"), col("source"), col("user.id").as("user_id"),
      col("in_reply_to_status_id"), col("in_reply_to_user_id"),
      col("lang"), col("retweet_count"), col("reply_count"), col("place.bounding_box.coordinates"),
      col("entities.hashtags"), col("entities.user_mentions")).withColumn("coordinates", explode(col("coordinates")))

    df_1.show(truncate = false)
    df_1.printSchema()

    df_1.write
      .format("jdbc")
      .option("url", "postgres_url")
      .option("dbtable", "xxx.mytable")
      .option("user", "user")
      .option("password", "pass")
      .save()

Пример ввода:

Столбец координат:

[[80.063341, 26.348309], [80.063341, 30.43339], [88.2027, 30.43339], [88.2027, 26.348309]]

User_Mentions:

[[123456789, 123456789, [0, 15], Name, ScreenName]]

1 Ответ

1 голос
/ 09 мая 2020

Spark поддерживает только чтение и запись одномерных массивов с помощью JDB C. Вы можете преобразовать ваши данные в несколько строк (например, explode он должен иметь double [] в нескольких строках) или вы можете преобразовать свои данные из double[][] в разделенные запятыми string[] или простые string.

например, [[1, 2], [3, 4]] можно преобразовать в ["1,2", "3,4"]

...