pg_bulkloadを使いたくなるケース
- 大量のデータをインポートしたい
- 中にはエラーがあるデータがちょこちょこある
に当てはまったので、インストールからやってみた。 やったこと順に列記するので最低限の手順ではないと思う。
rpmからインストールする方法でなく、ソースからやってみることにした。 Ubuntu12.04でインストールしたけど、他のバージョンでもほぼ同じだと思う。
ソースの取得
まずは最新のstableをgithubから取ってくる。ブログ執筆時はこんな感じ。
$ git clone -b VERSION3_1_STABLE https://github.com/ossc-db/pg_bulkload.git
make(失敗)
おもむろにmakeしてみると
$ cd pg_bulkload
$ make
するとpgxs.xmlが無い!というエラーが出て来た
Makefile:17: /usr/lib/postgresql/9.4/lib/pgxs/src/makefiles/pgxs.mk: そのようなファイルやディレクトリはありません
postgresqlは9.2しか入れてないはずなのに何故か9.4のファイルが無いとか言われた。
試行錯誤(失敗)
どうもMakefileを調べてみると、ここで出てくるバージョンはpg_configコマンドで取得するバージョンらしい。面倒なので、手動で9.2のファイルを設定するように変更して、さらにpgxs.mkを入れるためにpostgresql-server-dev-9.2をaptitudeでインストールした。
で、おもむろにmakeすると・・・
$ sudo make
....
/usr/include/postgresql/libpq-fe.h:547:1: エラー: 不明な型名 ‘pg_int64’ です
/usr/include/postgresql/libpq-fe.h:547:50: エラー: 不明な型名 ‘pg_int64’ です
/usr/include/postgresql/libpq-fe.h:551:1: エラー: 不明な型名 ‘pg_int64’ です
/usr/include/postgresql/libpq-fe.h:553:48: エラー: 不明な型名 ‘pg_int64’ です
make[1]: *** [pg_bulkload.o] エラー 1
make[1]: ディレクトリ `/****/pg_bulkload/bin' から出ます
make: *** [all] エラー 2
と結局エラーが出てしまった。ググって調べるとどうもlibpqのバージョンが関連するらしい。調べてみると
$ aptitude show libpq-dev
パッケージ: libpq-dev
状態: インストール済み
自動的にインストールされた: いいえ
バージョン: 9.4.0-1.pgdg12.4+1
....
バージョンが9.4になっていたorz。多分だけど、9.2でpg_bulkloadをインストールするにはlibpqをダウングレードしないといけないっぽい。それは面倒なのでpostgresqlのバージョン9.4をインストールすることでバージョンを合わせることにした
$ sudo aptitude install postgresql-9.4
$ sudo aptitude install postgresql-server-dev-9.4
インストールの途中でlibpq-devは削除することになった。
make(成功)
バージョンを合わせたので、makeしてみると今度はライブラリが足らないというエラーが出た
$ sudo make
....
/usr/bin/ld: cannot find -lpam
/usr/bin/ld: cannot find -ledit
collect2: ld はステータス 1 で終了しました
make[1]: *** [pg_bulkload] エラー 1
make[1]: ディレクトリ `/***/pg_bulkload/bin' から出ます
make: *** [all] エラー 2
これはubuntuではlibpam-devとlibedit-devが足らないという意味らしいので、aptitudeからインストールした。
$ sudo aptitude install libpam-dev
$ sudo aptitude install libedit-dev
以上の作業でpg_bulkloadのmakeに成功した
$ sudo make
$ sudo make install
使ってみる
pg_bulkloadはbinフォルダ内にある。使い方は
- 設定ファイルを書く
- csvファイルを用意する
- 実行する
となる。
設定ファイルを書く
設定ファイルの例はこんな感じ(下のコマンドの場合、example.ctlで保存しておく)、bin/data内にも例があるので参考になる。 この設定は
- リダイレクトでcsvファイルを入力する。
- リレーションをチェックする。リレーションにミスがある場合はエラーにする
- タブ区切り
TYPE = CSV
INPUT = stdin
TABLE = table_name
CHECK_CONSTRAINTS = YES
DELIMITER = " " #タブの場合
WRITER = DIRECT
コマンドはこんな感じ
$ ./pg_bulkload example.ctl --dbname db_name < csv_name.csv
NOTICE: BULK LOAD START
NOTICE: BULK LOAD END
0 Rows skipped.
10 Rows successfully loaded.
0 Rows not loaded due to parse errors.
0 Rows not loaded due to duplicate errors.
0 Rows replaced with new rows.
csvファイルはpsqlで\d table_nameで表示される順序にしておくこと。でないとパースエラーが出る。
順序が変わる場合
csvファイル内のフィールド順序をdb内の順序と違うものにしたい場合や、idなど、データを省略したい場合はフィルタを指定出来る。フィルタは
- db内に関数を作る
- 設定ファイルでフィルタを指定
で設定する。
フィルタの例
CREATE FUNCTION sample_filter(integer, text, text, real DEFAULT 0.05) RETURNS record
AS $$ SELECT $1 * $4, upper($3) $$
LANGUAGE SQL;
設定ファイル
TYPE = CSV
INPUT = stdin
TABLE = table_name
CHECK_CONSTRAINTS = YES
DELIMITER = " " #タブの場合
WRITER = DIRECT
FILTER = sample_filter
出来てない点(追記予定)
- MULTI_PROCESS = YESの時に認証失敗する件
参考: