2

私は最近新しい会社に加わり、Python(彼らが好むスクリプト言語)に不慣れで、cx_oracleを使用していくつかのETLプロセスを作成しています。これまでに作成したスクリプトは、OracleソースDBから必要な列のサブセットを選択し、外部プロセスがそのデータの読み取りとターゲットへの挿入を待機している名前付きパイプに出力を書き込むシングルスレッドジョブです。 。

これは、5億から20億行の範囲にあるいくつかのテーブルに到達するまでは正常に機能しました。ジョブは引き続き機能しますが、完了するまでに何時間もかかります。これらの大きなソーステーブルはパーティション化されているため、異なるパーティションの並列読み取りを調整して、2つ以上のスレッドを同時に動作させ、それぞれが別々の名前付きパイプに書き込む方法を研究しようとしています。

同じテーブルの異なるパーティションから読み取る複数のスレッドを処理するためのエレガントな方法がcx-oracleにありますか?

これが私の現在の(単純な)コードです:

import cx_Oracle
import csv

# connect via SQL*Net string or by each segment in a separate argument
connection = cx_Oracle.connect("user/password@TNS")


csv.register_dialect('pipe_delimited', escapechar='\\' delimiter='|',quoting=csv.QUOTE_NONE)

cursor = connection.cursor()
f = open("<path_to_named_pipe>", "w")

writer = csv.writer(f, dialect='pipe_delimited', lineterminator="\n")
r = cursor.execute("""SELECT <column_list> from <SOURCE_TABLE>""")
for row in cursor:
        writer.writerow(row)
f.close()

一部のソーステーブルには1000を超えるパーティションがあるため、パーティション名をハードコーディングすることはお勧めしません。私はパーティション名の配列を設定してそれらを反復処理することを考えていましたが、他のアイデアがあれば聞いてみたいと思います。

4

1 に答える 1

1

まず、*cx_Oracle* がスレッドセーフであることを確認する必要があります。これはPython DB API Spec v2.0を実装しているため、threadsafetyモジュール グローバルを確認するだけです。値2または3DB への複数の接続を開き、同時に複数のクエリを実行できることを意味します。これを行う最善の方法は、非常に使いやすいthreadingモジュールを使用することです。これは、それを始める方法についての短くて甘い記事です。

もちろん、クエリをパイプライン化してもパフォーマンスが大幅に向上するという保証はありません (DB エンジン、I/O などの理由による) が、試してみる価値は間違いなくあります。幸運を!

于 2011-09-23T15:43:29.160 に答える