Я пытаюсь получить данные из оракула, используя версию spark-sql-2.4.1. Я попытался установить JdbcOptions, как показано ниже:

    .option("lowerBound", "31-MAR-02");
    .option("upperBound", "01-MAY-19");
    .option("partitionColumn", "data_date");
    .option("numPartitions", 240);

Но выдает ошибку:

    java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
        at java.sql.Timestamp.valueOf(Timestamp.java:204)
        at org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation$.toInternalBoundValue(JDBCRelation.scala:179)

Потом попробовал как ниже

    .option("lowerBound", "2002-03-31"); //changed the date format
    .option("upperBound", "2019-05-02");
    .option("partitionColumn", "data_date"); 
    .option("numPartitions", 240);

Все еще не повезло. Итак, как правильно передать дату как "lower / upperBound"? Есть ли способ указать / установить параметр параметра Тип данных?

< Сильный > Part- 2 Проверены параметры правильно. они были перезаписаны перед выполнением запроса. Так что поправил. ... теперь эта ошибка устранена.

Но для ниже вариантов:

.option("lowerBound", "2002-03-31 00:00:00"); 
.option("upperBound", "2019-05-01 23:59:59");
.option("timestampFormat", "yyyy-mm-dd hh:mm:ss");

Строка запроса :

query ->  ( SELECT * FROM MODEL_VALS ) T

Это бросает другую ошибку:

java.sql.SQLException: ORA-12801: error signaled in parallel query server P022, instance nj0005

ORA-01861: literal does not match format string
8
BdEngineer 3 Май 2019 в 11:27

4 ответа

Лучший ответ

Если вы используете Oracle, см. https://github.com/apache/spark/blob/master/external/docker-integration-tests/src/test/scala/org/apache/spark /sql/jdbc/OracleIntegrationSuite.scala#L441

val df1 = spark.read.format("jdbc")
      .option("url", jdbcUrl)
      .option("dbtable", "datetimePartitionTest")
      .option("partitionColumn", "d")
      .option("lowerBound", "2018-07-06")
      .option("upperBound", "2018-07-20")
      .option("numPartitions", 3)
      // oracle.jdbc.mapDateToTimestamp defaults to true. If this flag is not disabled, column d
      // (Oracle DATE) will be resolved as Catalyst Timestamp, which will fail bound evaluation of
      // the partition column. E.g. 2018-07-06 cannot be evaluated as Timestamp, and the error
      // message says: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff].
      .option("oracle.jdbc.mapDateToTimestamp", "false")
      .option("sessionInitStatement", "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'")
      .load()
2
alexm 27 Июл 2019 в 00:51

Указанные параметры имеют тип отметки времени, но вы указываете единственную дату. Временная метка имеет формат yyyy-mm-dd hh:mm:ss, поэтому вам необходимо указать даты как 2002-03-31 00:00:00 и 2019-05-01 23:59:59 соответственно ...

2
Alex Ott 3 Май 2019 в 08:59

Все следующие параметры должны быть установлены таким образом, чтобы он работал:

spark.read
      .option("header", true)
      .option("inferSchema", true)
      .option("timestampFormat", "MM/dd/yyyy h:mm:ss a")
      .csv("PATH_TO_CSV")
1
raam86 6 Май 2019 в 09:00

Я наткнулся на этот вопрос, поскольку я решаю подобную проблему. Но в этом случае Spark 2.4.2 отправляет дату в формате «гггг-ММ-дд ЧЧ: мм: сс.сссс» в Oracle и возвращает «Недействительный месяц», как и ожидалось, «дд-МММ-гг чч: мм : ss.ssss . Чтобы решить эту проблему, я следовал: Spark GitHub Link, это говорит:

Переопределите метод beforeFetch в OracleDialect, чтобы завершить следующие две вещи:

Установите для Oracle значение NLS_TIMESTAMP_FORMAT, равное «ГГГГ-ММ-ДД ЧЧ24: MI: SS.FF», в соответствии с форматом java.sql.Timestamp. Установите для Oracle NLS_DATE_FORMAT значение «ГГГГ-ММ-ДД», чтобы оно соответствовало формату java.sql.Date.

И это решило проблему. Надеюсь, поможет.

3
Ankush 29 Июн 2019 в 11:51