1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SparkからOracleへのjdbc接続時に沼った話

Last updated at Posted at 2023-08-31

Databricks上のPySparkからjdbc経由でOracleに接続するパフォーマンスチューニングをしていたら解消までに沼ってだいぶ時間を要したので、備忘として書き残しておきます。

やっていたこと

Databricks上で上記参考にpartitionColumn、lowerBound、upperBoundにタイムスタンプ列を使ってreadしようとしたところ、以下のようなエラーが発生

PySpark
jdbcDF = spark.read \
    .format("jdbc") \
    .option("url", <URL>) \
    .option("dbtable", <table>) \
    .option("user", <user>) \
    .option("password", <password>) \
    .option("numPartitions", spark.default.parallelism) \
    .option("partitionColumn", <TIMESTAMP>) \
    .option("lowerBound", "2018-01-01 00:00:00") \
    .option("upperBound", "2022-12-31 23:59:59") \
    .load()
Error
ORA-01843: not a valid month

結論

PySpark
jdbcDF = spark.read \
    .format("jdbc") \
    .option("url", <URL>) \
    .option("dbtable", <table>) \
    .option("user", <user>) \
    .option("password", <password>) \
    .option("numPartitions", spark.default.parallelism) \
    .option("partitionColumn", <TIMESTAMP>) \
    .option("lowerBound", "2018-01-01 00:00:00") \
    .option("upperBound", "2022-12-31 23:59:59") \
    .option("sessionInitStatement", "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'  NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") \
    .load()

sessionInitStatementに複数指定する方法が分からなかったり、色々な所に沼ポイントがありました。
(はじめは以下のように書いて通らず苦しんでいた。sessionInitStatementを複数回やると一番最後のもので上書きされる。)

誤った設定値の例
.option("sessionInitStatement", "ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") \
.option("sessionInitStatement", "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD')

突破口になったのは以下の構文でセッションパラメータを抜いてくることでした。
これで「最後に指定した奴しか効いてない」に気付けました。

PySpark
jdbcDF = spark.read \
    .format("jdbc") \
    .option("url", <URL>) \
    .option("query", "SELECT * FROM nls_session_parameters") \
    .option("user", <user>) \
    .option("password", <password>) \
    .load()

ちなみに以下のようにHH24:MI:SSまでで止めてしまうと、lowerBoundからupperBoundまでの間の計算でほぼ確実に秒に端数が出るので以下のようなエラーになります。

誤った設定値の例
.option("sessionInitStatement", "ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'") \
Error
ORA-01830: date format picture ends before converting entire input string

同じところでハマる人の目に留まりますよう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?