Загрузить файл CSV в качестве фрейма данных из ресурсов в Uber Jar - PullRequest
0 голосов
/ 25 сентября 2019

Итак, я создал приложение Scala для запуска в Spark и создал Uber Jar, используя sbt> assembly.

Загружаемый файл является поиском, необходимым приложению, поэтому идея состоит в том, чтобы упаковать еговсе вместе.Он прекрасно работает в InteliJ, используя путь "src / main / resources / lookup01.csv"

Я занимаюсь разработкой в ​​Windows, тестирую локально, чтобы развернуть его на удаленном тестовом сервере.

Но когда я вызываю spark-submit на компьютере с Windows, я получаю сообщение об ошибке:

"org.apache.spark.sql.AnalysisException: путь не существует: file: / H: / dev / Spark /spark-2.4.3-bin-hadoop2.7 / bin / src / main / resources / "

Кажется, что он пытается найти файл в местоположении спаркхома, а не внутри файла JAr.

Как я могу выразить путь, чтобы он работал, просматривая файл из пакета JAR?

Пример кода, как я загружаю Dataframe.После загрузки я превращаю его в другие структуры, такие как Карты.

val v_lookup = sparkSession.read.option( "header", true ).csv( "src/main/resources/lookup01.csv")

Чего я хотел бы добиться, так это получить способ выразить путь, чтобы он работал в любой среде, я пытаюсь запустить JAR, в идеале работая также изнутри InteliJ при разработке.

Редактировать: версия scala 2.11.12

Обновление:

Похоже, что, чтобы получить руку в файле внутри JAR, я должен прочитать его как поток, приведенный ниже код работал, но я не могу найти безопасный способ извлечь заголовки файла, такие как SparkSession.read.option.

val fileStream = scala.io.Source.getClass.getResourceAsStream("/lookup01.csv")
val inputDF = sparkSession.sparkContext.makeRDD(scala.io.Source.fromInputStream(fileStream).getLines().toList).toDF

Когда применяется makeRDD, я получаю RDD изатем можно преобразовать его в фрейм данных, но, похоже, я утратил способность использовать опцию «read», которая анализировала заголовки как схему.

Любой способ обойти это при использовании makeRDD?

Другая проблема заключается в том, что мне, кажется, придется вручную разбивать строки на столбцы.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2019

Итак, все это указывает на то, что после того, как файл находится внутри JAR, к нему можно получить доступ только как к входному потоку для чтения фрагмента данных из сжатого файла.

Я пришел к решению, дажехотя это не очень красиво, он делает то, что мне нужно, то есть читает файл csv, берет 2 первых столбца и превращает их в массив данных, а затем загружает его в структуру ключ-значение (в этом случае я создал класс case для храненияэти пары).

Я рассматриваю перенос этих поисков в файл HOCON, который может сделать процесс менее сложным для загрузки этих поисков


import sparkSession.implicits._
val fileStream = scala.io.Source.getClass.getResourceAsStream("/lookup01.csv")
val input = sparkSession.sparkContext.makeRDD(scala.io.Source.fromInputStream(fileStream).getLines().toList).toDF()

val myRdd = input.map {
      line =>
        val col = utils.Utils.splitCSVString(line.getString(0))
        KeyValue(col(0), col(1))
    }

val myDF = myRdd.rdd.map(x => (x.key, x.value)).collectAsMap()

fileStream.close()
0 голосов
/ 25 сентября 2019

Вы должны получить правильный путь из classPath

Учитывая, что ваш файл находится в каталоге src / main / resources:

val path = getClass.getResource("/lookup01.csv")

val v_lookup = sparkSession.read.option( "header", true ).csv(path)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...