事故は現場で起きているんだ

システムエンジニアの奮闘記

Treasure DataのData Connector for MySQLを利用する際の注意事項

今やってるシステム開発作業で、MySQLのデータを「主データ」としてTreasure Data(以下、TD)へアップロードする必要があったので、TDが提供するData Connector for MySQL(以下、Data Connector)を試してみたことのメモ書き。 ちなみに、該当機能のマニュアルは下記リンクを参照。

docs.treasuredata.com

背景

システムで利用する「主データ」のアップロードフローで、TDのDATA Connectorを使ってMySQLからTDへダイレクト登録ができるようにする。 ちなみに、システムで利用する「主データ」は約30個ある。

アップロードフロー

  1. Data Connectorの利用に必要なConfigファイル作成(xxx_seed.yml)
  2. TDコマンド(td connector:guess)を使って、Configファイル(xxx_seed.yml)からアップロード用ファイル作成(xxx_load.yml)
  3. TDコマンド(td connector:issue)を使って、アップロード用ファイル(xxx_load.yml)に基づいて、MySQLからTDへダイレクトでデータアップロード

Configファイルのサンプル(初期バージョン)

in:
  type: mysql
  host: ホスト情報
  port: ポート番号(3306)
  user: ユーザID
  password: パスワード
  database: mysql側のDB名
  query: "SELECT id
       , title
       , category
       , target_date
  FROM DB名.テーブル名
 WHERE target_date = '2016-11-04'
;
"
out:
  mode: append

問題点発見!

データ処理対象日である「target_date」は、TDのテーブルでは下記形式で保存される必要がある。

YYYY-mm-dd (例:2016-11-03)

しかし、DATA Connectorを利用すると、下記のように登録されてしまう。

YYYY-mm-dd HH:MM:SS[.fraction] (例:2016-11-03 00:00:00.000)

原因

結論から言うと、DATA Connectorの仕様だった。
※DATA Connectorは裏側ではembulkを使っている。

github.com

上記リンクページを「timestamp_format」で調べてみると、

  • MySQLのテーブル.カラムのデータ型:date/time/datetime
  • TDのテーブル.カラムのデータ型:string

の場合、データ型がtimestamp_formatとして適用される仕様らしい。

解決策

同じリンクページに書いてあるように、Configファイルへ「column_options」項目を追加してあげればOK。

  column_options:
    target_date: {type: string, timestamp_format: "%Y-%m-%d", timezone: "+0900"}

Configファイルのサンプル(解決バージョン)

in:
  type: mysql
  host: ホスト情報
  port: ポート番号(3306)
  user: ユーザID
  password: パスワード
  database: mysql側のDB名
  query: "SELECT id
       , title
       , category
       , target_date
  FROM DB名.テーブル名
 WHERE target_date = '2016-11-04'
;
"
  column_options:
    target_date: {type: string, timestamp_format: "%Y-%m-%d", timezone: "+0900"} # timezoneでは日本時間を指定
    open_date: {type: string, timestamp_format: "%Y-%m-%d", timezone: "+0900"}  # ←この行の説明は下にあるよー
out:
  mode: append

ちなみに、Configファイルは、アップロードするテーブルの数と同じ数が必要。つまり、今回だと約30個のConfigファイルが必要。

従って、Configファイルのテンプレートファイルを用意して、各テーブルごとに適切なConfigファイルを自動的に作ってくれるロジックを作成した。

ちょっと待って、その場合、「column_options」はどうする?テーブルによっては、「target_date」だけではなく、「open_date」や「close_date」等、日付形カラムが複数あったり異なったりの場合があるよねー。それをテーブルごとに変数化してロジックに渡す??

あんまり望ましくないやり方だな…

それで試してみたのが上記サンプルコードのように、「column_options」への項目追加。 つまり、該当テーブルでは使ってないけど、他のテーブルで使ってるカラムもテンプレートファイルにまとめて書いて置けば、各テーブルで該当するカラムだけをいい感じなデータ型に変更してくれるし、エラーにもならない!
※サンプルコードの場合だと、「target_date」カラムが「YYYY-mm-dd」のデータ型に変わる。

これで問題解決!

以上、TDのDATA Connectorを利用する際の注意事項ー