COPY

名前

COPY -- ファイルとテーブルの間でデータをコピーする

概要

COPY tablename [ ( column [, ...] ) ]
    FROM { 'filename' | STDIN }
    [ [ WITH ] 
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ HEADER ]
                [ QUOTE [ AS ] 'quote' ] 
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE NOT NULL column [, ...] ]

COPY { tablename [ ( column [, ...] ) ] | ( query ) }
    TO { 'filename' | STDOUT }
    [ [ WITH ] 
          [ BINARY ]
          [ HEADER ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ HEADER ]
                [ QUOTE [ AS ] 'quote' ] 
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE QUOTE column [, ...] ]

説明

COPYコマンドは、PostgreSQLのテーブルと標準のファイルシステムのファイル間でデータを移動します。 COPY TOコマンドはテーブルの内容をファイルコピーします。 また、COPY FROMコマンドは、ファイルからテーブルへとデータをコピーします(この時、既にテーブルにあるデータにコピーした内容を追加します)。 また、COPY TOによりSELECT問い合わせの結果をコピーすることができます。

列のリストが指定されている場合、COPYは、指定された列間のコピーのみを行います。 列リストに含まれていない列がテーブル内にある場合、COPY FROMは、それらの列にデフォルトの値を挿入します。

ファイル名付きのCOPYコマンドは、PostgreSQLサーバに対して直接ファイルへの読み書きをするように命じます。 指定したファイルは必ずサーバからアクセスできる必要があります。また、ファイル名はサーバから見たように指定されなければなりません。 STDINSTDOUTが指定された場合、データはクライアントとサーバ間を流れます。

パラメータ

tablename

既存のテーブルの名前です(スキーマ修飾名も可)。

column

コピーする列のリストです。このパラメータは省略可能です。 列のリストが指定されていない場合は、テーブルの全ての列がコピーされます。

query

指定したSELECTコマンドまたはVALUESコマンドの結果がコピーされます。 問い合わせを括弧でくくる必要があることに注意してください。

filename

入出力ファイルの絶対パス名です。 Windowsユーザの場合、パスの区切りとしてスラッシュを使用する際にはE''文字列を使用し、二重にする必要があるかもしれません。

STDIN

入力がクライアントアプリケーションからのものであることを指定します。

STDOUT

出力がクライアントアプリケーションへのものであることを指定します。

BINARY

全てのデータをテキストではなくバイナリ形式で読み書きするように設定します。 バイナリモードではDELIMITERNULLCSVオプションを指定することはできません。

OIDS

各行のOIDをコピーするよう指定します (OIDを持たないテーブルにOIDSを指定する場合、または、queryコピーの場合、エラーが発生します)。

delimiter

ファイルの各行(ライン)の列を区切る1つのASCII文字です。 デフォルトは、テキストモードではタブ文字、CSVモードではカンマです。

null string

NULL値を表す文字列です。 デフォルトは、テキストモードでは\N(バックスラッシュN)、CSVモードでは引用符のない空値です。 しかし、NULL値と空文字列を区別する必要がない場合は、テキストモードであっても空文字列を使用した方が良いかもしれません。

注意: COPY FROMの場合、この文字列と一致するデータ要素はNULL値として格納されます。 COPY TO実行時に使用した同じ文字列を使用しているかどうか確認してください。

CSV

カンマ区切り変数(CSV)モードを選択します。

HEADER

ヘッダ行を含むファイルを指定します。 このファイルには各列の名前が記載されています。 出力では、先頭行にテーブルの列名が入り、入力では先頭行は無視されます。

quote

CSVにおける引用符用のASCII文字を指定します。 デフォルトは二重引用符です。

escape

CSVモードにおけるデータ文字列内のQUOTEの前に現れるASCII文字を指定します。 デフォルトはQUOTEの値(通常は二重引用符)です。

FORCE QUOTE

CSVモードのCOPY TOにおいて、指定された各列内にある全ての非NULL値を強制的に引用符で囲みます。 NULL出力は引用符で囲まれません。

FORCE NOT NULL

CSVモードのCOPY FROMにおいて、指定された各列を引用符で囲まれているものとみなし、NULL値はないものとして処理されます。 CSVモードのデフォルトのNULL文字列('')が存在する場合、これにより値が消失し、空文字列として入力されます。

出力

正常に完了した場合、COPYコマンドは以下の形式のコマンドタグを返します。

COPY count

countはコピーされた行数です。

注釈

COPYは通常のテーブルに対してのみ使用することができます。 ビューに対して使用することはできません。 しかし、COPY (SELECT * FROM viewname) TO ...と記述することができます。

BINARYキーワードを指定すると、全てのデータをテキスト形式ではなく、バイナリ形式として書き込み/読み込みを行います。 通常のテキストモードより多少動作が速くなりますが、バイナリ形式のファイルは、異なるマシンアーキテクチャや他のバージョンのPostgreSQLでは使用できません。

COPY TOの場合は値を読み込むテーブルに対するSELECT権限が、COPY FROMの場合は値を挿入するテーブルに対するINSERT権限が必要です。

COPYコマンドで指定するファイルは、クライアントアプリケーションではなく、サーバが直接読み込み/書き込みを行います。 したがって、それらのファイルは、クライアントではなく、データベースサーバマシン上に存在するか、または、データベースサーバマシンからアクセス可能である必要があります。 さらに、クライアントではなく、PostgreSQLユーザ(サーバを実行しているユーザID)が、アクセス権限と読み書き権限を持っている必要があります。 ファイル名を指定したCOPYコマンドの実行は、データベースのスーパーユーザのみに許可されています。このコマンドによって、サーバがアクセス権限を持つ全てのファイルの読み込み、書き込みが可能になってしまうためです。

COPYpsql\copyとは異なるものであることに注意してください。 \copyCOPY FROM STDINCOPY TO STDOUTを呼び出し、psqlクライアントからアクセスできるファイルにデータの書き込み/読み込みを行います。 したがって、\copyコマンドでは、ファイルへのアクセスが可能かどうかと、ファイルに対するアクセス権限の有無は、サーバではなくクライアント側に依存します。

COPYでファイル名を指定する時は、常に絶対パスで記述することをお勧めします。 COPY TOコマンドの場合はサーバによって強制的に絶対パス指定にさせられますが、COPY FROMコマンドでは相対パスで指定されたファイルを読み込むことも可能となっています。 後者では、クライアントの作業ディレクトリではなく、サーバプロセスの作業ディレクトリ(通常はクラスタのデータディレクトリ)からの相対的なディレクトリとして解釈されます。

COPY FROMは、宛先テーブル上で任意のトリガとチェック制約を呼び出しますが、ルールは呼び出しません。

COPYの入出力はDateStyleの影響を受けます。 デフォルト以外のDateStyleが設定された可能性があるPostgreSQLインストレーションとの移植を確実に行いたい場合は、COPYを使う前にDateStyleISOに設定しなければなりません。

COPYでは、エラーが発生するとすぐに処理を停止します。 COPY TOコマンドの実行では何ら問題ありませんが、COPY FROMの場合は、対象となるテーブルは初めの方の行を既に受け取っています。 これらの行は不可視となり、アクセスすることもできませんが、ディスク領域を占有します。 したがって、大きなコピー処理に何度も失敗した場合には、無視できないほど無駄なディスク領域が増えてしまいます。 この無駄な領域を取り戻すには、VACUUMを行う必要があります。

ファイルの形式

テキスト形式

COPYBINARYオプションまたはCSVオプションを付加しないで使用した場合、読み書きされるデータはテーブルの1つの行を1行で表したテキストファイルとなります。 行内の列は区切り文字で区切られます。 属性値自体は、その属性のデータ型の出力関数で生成された、または、その入力関数で受け付け可能な文字列です。 値がNULLの列では、代わりに指定されたNULL値を表す文字列が使用されます。 入力ファイルのいずれかの行にある列数が予期された数と違う場合、COPY FROMはエラーを発生します。 OIDSが指定された場合、OIDは、ユーザデータの列の前にある、1番目の列として読み書きされます。

データの終了は、バックスラッシュとピリオド(\.)のみから構成される1行で表されます。 EOF(ファイルの終了)を使えば同じことが実現できるので、ファイルからの読み込みの場合はデータ終了マークは不要です。 しかし、3.0以前のクライアントプロトコルを使用したクライアントアプリケーションとデータのコピーを行う場合だけは、読み込み、書き込みを問わず、終了マークが必要です。

バックスラッシュ文字(\)は、COPY対象データ内で、行や列の区切り文字と判定される可能性があるデータ文字列の引用符付けに使用します。 特に、バックスラッシュ自体、改行、使用中の区切り文字などの文字が列の値に含まれている場合は、必ず前にバックスラッシュを付けなければなりません。

指定されたNULL文字列はバックスラッシュを付けずにCOPY TOに送られます。 一方、COPY FROMでは、バックスラッシュを削除する前にNULL文字列と入力が比較されます。 したがって、\NといったNULL文字列が実際の\Nというデータ値と混乱することはあり得ません。 (これは\\Nとして表現されます。)

COPY FROMは、バックスラッシュで始まる次のような文字の並びを識別します。

文字の並び表現
\bバックスペース(ASCII 8)
\f改ページ(ASCII 12)
\n改行(ASCII 10)
\r復帰(ASCII 13)
\tタブ(ASCII 9)
\v垂直タブ(ASCII 11)
\数字バックスラッシュに続き1から3個の8進数の数字をコード番号として指定すると、そのコードが表す文字を指定できます。
\xdigitsバックスラッシュ、x という並びに続き1から2個の16進数の数字をコード番号として指定すると、そのコードが表す文字を指定できます。

現在、COPY TOは、バックスラッシュの後ろに8進数や16進数を付けた形式で文字を出力することはありませんが、上記一覧に存在しない制御文字が含まれている場合は、この形式を使用します。

上表で記載されていないバックスラッシュ付きの文字はすべて、そのまま解釈されます。 しかし、不要なバックスラッシュの追加には注意してください。 偶然にデータを終わりを示す印(\.)やヌル文字列(デフォルトでは\N)と合致する文字列を生成してしまうかもしれないためです。 これらの文字列は他のバックスラッシュの処理を行う前に解釈されます。

COPYデータを生成するアプリケーションは、データ内の改行と復帰をそれぞれ、\n\rに変換することを強く推奨されています。 現在のところ、バックスラッシュと復帰文字でデータ内の復帰を表したり、バックスラッシュと改行文字でデータ内の改行を表すことが可能です。 しかし、こういった表現は今後のリリースでは、受け付けられなくなる可能性があります。 また、COPYファイルが異なるマシンをまたがって転送される場合、破損するおそれがかなりあります (例えば、UnixからWindowsあるいはその逆)。

COPY TOは各行の行末にUnix形式の改行("\n")を出力します。 なお、Microsoft Windowsで稼働するサーバの場合は、サーバ上のファイルへのCOPYの場合にのみ復帰/改行("\r\n")を出力します。 プラットフォームをまたがる一貫性のために、サーバのプラットフォームにかかわらず、COPY TO STDOUTは常に"\n"を送信します。 COPY FROMは、改行、復帰、復帰/改行を行末として扱うことができます。 データを意図したバックスラッシュのない改行や復帰によるエラーの危険性を減らすために、COPY FROMは、入力行の行末が全て共通でない場合に警告を発します。

CSV形式

この形式は、スプレッドシートなど他の多くのプログラムで使用されるカンマ区切り値(CSV)ファイル形式をインポート、エキスポートするために使用されます。 PostgreSQLの標準テキストモードで使用されるエスケープの代わりに、一般的なCSVのエスケープ機構を生成、認識します。

各レコードの値はDELIMITER文字で区切られます。 区切り文字、QUOTE文字、NULL文字列、復帰、改行文字を含む値の場合、全体の値の前後にQUOTE文字が付与されます。値の中でQUOTE文字やESCAPE文字が現れる場合、その前にエスケープ用の文字が付与されます。 また、FORCE QUOTEを使用して、特定列内の非NULL値を出力する時に強制的に引用符を付与することもできます。

CSV書式にはNULL値と空文字列とを区別する標準的な方法はありません。 PostgreSQLのCOPYでは、引用符によってこれを区別しています。 NULLNULL文字列として出力され、引用符で囲まれません。 一方、NULL文字列に一致するデータ値は引用符で囲まれます。 その結果、デフォルトの設定を使用すると、NULLは引用符で囲まれない空文字列として、一方、空文字列は二重引用符で囲まれて("")出力されます。 データの読み込みの際も同様の規則に従います。 FORCE NOT NULLを使用して、特定列に対しNULL入力の比較を行わないようにすることもできます。

CSV書式ではバックスラッシュは特別な文字ではありませんので、データ終端記号\.はデータ値として現れることがあります。 誤った解釈を防ぐために、行内の一項目として\.というデータ値が現れる場合、出力に自動的に引用符が付けられます。 また、入力では引用符で括られた場合データ終端記号として解釈されません。 単一の引用符で括られない列で\.という値を持つ可能性がある、他のアプリケーションで作成されたファイルをロードしようとする場合、入力ファイル内のこうした値を引用符で括る必要があります。

注意: CSVモードでは文字はすべて意味を持ちます。 空白文字で括られた単一引用符やDELIMITER以外の任意の文字がこうした文字に含まれます。 これにより、固定長にするためにCSVの行に空白文字を埋めるシステムから取り出したデータをインポートする時にエラーが発生する可能性があります。 このような状況になった場合、PostgreSQLにデータをインポートする前に、そのCSVファイルから行末の空白を除去する前処理が必要になります。

注意: CSVモードは、復帰文字や改行文字が埋め込まれ引用符で囲まれた値を含むCSVファイルを認識し、生成します。 したがって、このファイルでは、テキストモードのように1つのテーブル行が1行で表されているとは限りません。

注意: 奇妙な(時には間違った)CSVファイルを生成するプログラムは多く存在するので、このファイル書式には標準よりも多くの慣習があります。 したがって、この機能でインポートできないファイルが存在するかもしれませんし、COPYが他のプログラムで処理できないファイルを生成するかもしれません。

バイナリ形式

COPY BINARYで使用されるファイル形式はPostgreSQL 7.4で変更されました。 新しい形式は、ファイルヘッダ、行データを含む0以上のタプル、ファイルトレーラから構成されます。 ヘッダとデータは、ネットワークバイトオーダになりました。

ファイルヘッダ

ファイルヘッダは15バイトの固定フィールドとその後に続く可変長ヘッダ拡張領域から構成されます。 固定フィールドは以下の通りです。

署名

PGCOPY\n\377\r\n\0という11バイトの並びです。 この署名の必須部分にNULLバイトが含まれていることに注意してください (この署名は、8ビットを通過させない転送方式によってファイルが破損した場合、これを容易に識別できるように設計されています。 署名は、改行コード変換やNULLバイトの削除、上位ビット落ち、パリティの変更などによって変化します)。

フラグフィールド

このファイル形式の重要な部分となる32ビット整数のビットマスクです。 ビットには0(LSB) から31(MSB)までの番号が付いています。 このフィールドは、このファイル形式で使用される他の全ての整数フィールドと同様、(最大バイトが最初に現れる)ネットワークバイトオーダで保存されていることに注意してください。 ファイル形式上の致命的な問題を表すために、16-31ビットは予約されています。 この範囲に想定外のビットが設定されていることが判明した場合、読み込み先は処理を中断しなければなりません。 後方互換における形式の問題を通知するために、0-15ビットは予約されています。 この範囲に想定外のビットが設定されていても、読み込み先は無視すべきです。 現在、1つのビットだけがフラグビットとして定義されており、残りは0でなければなりません。

ビット16

1ならば、OIDがデータに含まれています。 0ならば、含まれていません。

ヘッダ拡張領域長

自分自身を除いた、ヘッダの残り部分のバイト長を示す32ビットの整数です。 現在、これは0となっており、すぐ後に最初のタプルが続きます。 今後、ヘッダ内に追加データを格納するような形式の変更があるかもしれません。 読み込み側では、ヘッダ拡張データの扱いがわからない場合、そのデータをスキップしなければなりません。

ヘッダ拡張領域は、それ自身で認識することができる塊の並びを保持するために用意されています。 フラグフィールドは読み込み先に拡張領域の内容を知らせるものではありません。 ヘッダ拡張内容の個々の設計は今後のリリースのために残してあります。

この設計によって、後方互換性を維持するヘッダの追加(ヘッダ拡張チャンクの追加や下位フラグビットの設定)と後方互換性のない変更(変更を通知するための高位フラグビットの設定や必要に応じた拡張領域へのサポート情報追加)の両方に対応できます。

タプル

全てのタプルはタプル内のフィールド数を表す16ビットの整数から始まります(現時点では、テーブル内の全てのタプルは同一のフィールド数を持つことになっていますが、今後、これは変更される可能性があります)。 その後に、タプル中のそれぞれのフィールドが続きます。これらのフィールドには、先頭にフィールドデータが何バイトあるかを表す32ビット長のワードが付けられています (このワードが表す長さには自分自身は含まれません。したがって、0になることもあります)。 特殊な値としてNULLフィールドを表す-1が用意されています。 このNULLが指定された場合、値用のバイトはありません。

フィールド間には整列用のパッドやその他の余計なデータはありません。

現在、COPY BINARYファイル内の全てのデータ値は、バイナリ形式(形式コード1)であると仮定されています。 将来の拡張によって、列単位に形式コードを指定するヘッダフィールドが追加されることを予想したものです。

実際のタプルデータとして適切なバイナリ形式を決定するためには、PostgreSQLのソース、特に各列のデータ型用の*send 関数と*recv関数(通常配布物内のsrc/backend/utils/adtディレクトリにあります)を調べなければなりません。

このファイルにOIDが含まれる場合、OIDフィールドがフィールド数ワードの直後に続きます。 これは、フィールドカウントを持たない点を除いて、通常のフィールドです。 特に長さワードがあるため、苦労することなく、4バイトのOIDも8バイトのOIDも扱うことができます。 また、これにより、望ましいと判断されれば、OIDをNULLとして表示することができます。

ファイルトレーラ

ファイルトレーラは、-1を含んだ、16ビットの整数ワードで構成されます。 タプルのフィールドカウントワードを使用すれば、このワードを容易に見分けることができます。

読み込み側は、フィールドカウントワードが-1でも、想定した列数でもなかった場合はエラーを報告しなければなりません。 これにより、何らかの理由でデータとの同期が取れなくなったことを判定する特別な検査を行うことが可能になります。

次の例では、フィールド区切り文字として縦棒(|)を使用してテーブルをクライアントにコピーします。

COPY country TO STDOUT WITH DELIMITER '|';

ファイルからcountryテーブルにデータをコピーします。

COPY country FROM '/usr1/proj/bray/sql/country_data';

名前が'A'から始まる国のみをファイルにコピーします。

COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy';

これはSTDINからテーブルにコピーするのに適したデータの例です。

AF      AFGHANISTAN
AL      ALBANIA
DZ      ALGERIA
ZM      ZAMBIA
ZW      ZIMBABWE

各行の空白文字は実際にはタブ文字であることに注意してください。

以下は同一のデータをバイナリ書式で出力したものです。 データをUnixユーティリティod -cを使ってフィルタしたものを示します。 テーブルには3列あり、最初のデータ型はchar(2)、2番目はtext、3番目はintegerです。 全ての行の3列目はNULL値です。

0000000   P   G   C   O   P   Y  \n 377  \r  \n  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0 003  \0  \0  \0 002   A   F  \0  \0  \0 013   A
0000040   F   G   H   A   N   I   S   T   A   N 377 377 377 377  \0 003
0000060  \0  \0  \0 002   A   L  \0  \0  \0 007   A   L   B   A   N   I
0000100   A 377 377 377 377  \0 003  \0  \0  \0 002   D   Z  \0  \0  \0
0000120 007   A   L   G   E   R   I   A 377 377 377 377  \0 003  \0  \0
0000140  \0 002   Z   M  \0  \0  \0 006   Z   A   M   B   I   A 377 377
0000160 377 377  \0 003  \0  \0  \0 002   Z   W  \0  \0  \0  \b   Z   I
0000200   M   B   A   B   W   E 377 377 377 377 377 377

互換性

標準SQLにはCOPY文はありません。

以下の構文は、PostgreSQLバージョン7.3より前に使用されていたもので、まだサポートされています。

COPY [ BINARY ] tablename [ WITH OIDS ]
    FROM { 'filename' | STDIN }
    [ [USING] DELIMITERS 'delimiter' ]
    [ WITH NULL AS 'null string' ]

COPY [ BINARY ] tablename [ WITH OIDS ]
    TO { 'filename' | STDOUT }
    [ [USING] DELIMITERS 'delimiter' ]
    [ WITH NULL AS 'null string' ]