S-JIS[2017-04-11] 変更履歴

Embulk PostgreSQL入力

EmbulkのPostgreSQLからの読み込みのメモ。


概要

PostgreSQLのテーブルから読み込むにはembulk-input-postgresqlを使う。

このプラグインを使う為には、embulk-input-postgresqlプラグインインストールしておく必要がある。

$ embulk gem install embulk-input-postgresql

$ embulk gem list embulk-input-postgresql
2017-04-11 23:35:06.271 +0900: Embulk v0.8.15

*** LOCAL GEMS ***

embulk-input-postgresql (0.8.2)

config.yml:

in:
  type: postgresql
  host: 192.168.1.1
  user: hishidama
  password: "password"
  database: hishidamadb
  table: embulk_example
  select: "id, account, time, purchase, comment"
  where: "comment <> 'embulk'"
out:
  

直接SQL(SELECT文)を書きたい場合は、table/select/whereではなくqueryを使う。

in:
  type: postgresql
  host: 192.168.1.1
  user: hishidama
  password: "password"
  database: hishidamadb
  query: |
    select id, account, time, purchase, comment
    from embulk_example
    where comment <> 'embulk'
out:
  

オプション

オプション名 説明 ymlの記述例 デフォルト値
type  
  type: postgresql
(必須)
host DBのホスト名。
  host: 192.168.1.1
(必須)
port DBのポート番号。
  port: 5432
5432
user DBにログインするユーザー名。
  user: hishidama
(必須)
password DBにログインする為のパスワード。
  password: zzz
空文字列(パスワード無し)
database DB名。
  database: hishidamadb
(必須)
schema スキーマ。
  schema: public
public
query SELECT文。
  query: |
    select column1, columne2
    from example
    where column1 = 123
query
または
table(+select+where)
のどちらかは必須。
table テーブル名。
小文字に変換されてダブルクォーテーションで囲まれて使用される。
  table: example
select カラム名。
  select: "column1, column2"
*
where 条件。
  where: "column1 = 123"
(全レコードが対象となる)
fetch_rows 一度にフェッチするレコード数。    
options JDBC接続情報のオプション。    
default_timezone デフォルトのタイムゾーン。
  default_timezone: 'Asia/Tokyo'
 
column_options カラムの出力定義。
PostgreSQLのdateやtimestampをEmbulkでstringとして扱う際の形式を指定する。
  column_options:
    col2: { type: string, timestamp_format: '%Y-%m-%d %H:%M:%S' }
 

設定ファイルの共通化


よくあるエラー

publicでないスキーマのテーブルが見つからない

テーブルが存在しているはずなのに「テーブルが見つからない」というエラーが出るケース。

java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: relation "Hoge" does not exist

(PostgreSQLはテーブル名を小文字で保持している。embulk-input-postgresqlでは、tableを大文字で指定しても小文字に変換されて使用されるので、大文字小文字違いで見つからないという事は無い)

スキーマを指定していない場合、デフォルトではpublicで扱われる。
実行ログを見ると以下のように表示されている。

2017-04-11 22:51:42.636 +0900 [INFO] (transaction): SQL: SET search_path TO "public"

このため、スキーマが「public」でないテーブルを読もうとすると「テーブルが見つからない」というエラーになる。
(スキーマがpublicだと、「SELECT 〜 FROM public.hoge;」と同等)

psql上でテーブル定義を表示すればスキーマが確認できる。

hishidamadb=> \d
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+---------
 mydata | hoge | table | admin

ymlファイルでschemaを定義すると、そのスキーマでテーブルを探すようになる。

in:
  type: postgresql
  host: 192.168.1.1
  user: hishidama
  password: "password"
  database: hishidamadb
  schema: mydata
  table: Hoge
〜

2017-04-11 22:59:48.248 +0900 [INFO] (transaction): SQL: SET search_path TO "mydata"

ビューを読もうとするとJSONのエラーが発生

tableにビュー名を指定してselectしようとした際に、JSONのエラーが発生したケース。

2017-04-11 16:30:30.549 +0900: Embulk v0.7.7
2017-04-11 16:30:32.407 +0900 [INFO] (preview): Loaded plugin embulk-input-postgresql (0.8.2)
2017-04-11 16:30:32.639 +0900 [INFO] (preview): SQL: SET search_path TO "public"
LoadError: load error: embulk/command/embulk_main -- java.lang.NoClassDefFoundError: org/embulk/spi/json/JsonParser
  require at org/jruby/RubyKernel.java:940
  require at uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb:54
     at file:/home/apis/.embulk/bin/embulk!/embulk/command/embulk_bundle.rb:55

embulk-input-postgresql 0.8.2ではビューの場合にJSONのカラムかどうかをチェックしようとするようで、しかしEmbulk本体のバージョンが古いとJSONライブラリーが入っていないのでエラーになったらしい。
JsonParserはEmbulk 0.8.0で追加されたらしいので、Embulk本体のバージョンをそれ以降にすれば大丈夫。

つまり、プラグインのバージョンを上げたらEmbulk本体のバージョンも上げた方が良いってことか(苦笑)


Embulk目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま