PostgreSQLでクエリの結果をファイルに出力する2009/07/28

ググっても、シェルからpsqlを呼んだ結果をファイルにリダイレクトする方法ばかりがヒットする現状はいかがなものかと思ったのでエントリをおこす。

psqlのターミナルモードで実行したクエリの結果をファイルに保存するメタコマンドは

\o [{filename||command}]
 以降の問い合わせの結果をfilename ファイルに保存、もしくは、以降の問い合わせの結果を別シェルに渡し、 command を実行します。引数がない場合、問い合わせの出力はstdoutにリセットされます。
 "問い合わせの結果" には全てのテーブル、コマンドの応答、データベースサーバからの注意はもちろん、データベースに問い合わせを行なう(\d のような)各種バックスラッシュコマンドの出力が含まれますが、エラーメッセージは含まれません。

Oracleのsqlplusにおける spoolコマンドのようなものですが、\oコマンドを実行すると、クエリの結果はコンソールには出力されなくなります。

再びコンソールに結果を出力するためには、 \oメタコマンドを引数なしで実行します。

また、標準では可読性を高めるため、出力はインデント等で整形され、区切り文字は'|'になっているはずですが、 これだと出力を後続のスクリプトで処理するが面倒なので、出力フォーマットとフィールドセパレータを変更します。

\pset format unaligned
\pset fieldsep '\t'

を設定するとTSVとして保存されるので、扱いやすくなるはずです。 (format のデフォルト値は aligned です)

余談

テーブル全体をエクスポート(インポート)する場合は、PostgreSQLの拡張SQLの COPY を使うと良いです。

copy (tablename) to (filename) エクスポート
copy (tablename) from (filename) インポート
  • デフォルトのデリミタはタブ文字("\t")
  • NULLのカラムには文字列"\n"(コントロールコードではありません。"\\n")が挿入される
  • copy (tablename) from (filename) は既存のテーブルに追記される

詳しいことは、COPY - PostgreSQL 8.4.0 付属ドキュメント参照。