LoginSignup
5
0

More than 1 year has passed since last update.

OracleDBからBigQueryへのETLで文字化けを解決する

Last updated at Posted at 2022-12-15

初めに

レガシーシステムのOracleDBデータをBigQueryへETLする必要があり、GCPのDataflowでETLをしましたが、
日本語のデータが文字化けしていたので、その回避した経験を記述します。

簡単に言えば

  1. 文字列byte化してクエリ、BigQueryへBYTES型で格納
  2. BigqueryのUDFを設定してBYTEからcp932形式の文字変換

処理順番

Oracle クエリ

SELECT
    UTL_RAW.CAST_TO_RAW(NAME) AS NAME,
    ...
    other_columns
FROM MEMBERS
WHERE condition

Dataflowの設定

Dataflow 提供テンプレートの JDBC to BigQueryで簡単にETLの設定ができる
※ 各設定値はサンプルです。
image.png

UDF(user defined function)の設定とクエリ

BigQueryでは、SQL式またはJavaScriptコードを使ってクエリで利用する関数を作成できる。

文字変換ライブラリ iconv-lite

こちらのライブラリはこれは jsファイルを提供してないので webpack でパッケージングする必要がありました。
※ webpackでパッケージングするとき参考にした記事:https://dev.classmethod.jp/articles/bigquery-javascript-udf/
パッケージングしたjsファイルはGCPプロジェクトのクラウドストレージにアップロードします。

UDF定義とクエリ実行

CREATE TEMP FUNCTION conv_test(x ARRAY<INTEGER>)
RETURNS STRING
LANGUAGE js AS """
return iconv_for_udf.decode(x, "CP932")
"""
OPTIONS (
  library = ["gs://project_gcp_storage/iconv-lite_bq-udf.js"]
)
;

select 
    NAME,
    conv_test(TO_CODE_POINTS(MEMBERID)) as converted_name
FROM `project.dataset.MEMBERS`

※ iconv-liteのdecode関数は buffer を引数として扱うのでクエリでBuffer Arrayに変換してUDFを呼び出す必要があった
iconv-liteの例(from iconv-lite github)

var iconv = require('iconv-lite');

// Convert from an encoded buffer to a js string.
str = iconv.decode(Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'win1251');

// Convert from a js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251');

// Check if encoding is supported
iconv.encodingExists("us-ascii")

結果

スクリーンショット_20221209_163404.jpg

まとめ

やり方、色々あると思いますが、チーム内のシステムに適用するための方法を探す中で一番簡単にできそうなやり方でした。
辿り着くまでは大変だったが、完成した流れは簡単でシンプルでした。
レガシーシステムのETLがまた今後あるかは別にして、なかなか良い勉強でした。

5
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
5
0