★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

COPY

名前

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

概要

COPY tablename [ ( column [, ...] ) ]
    FROM { 'filename' | STDIN }
    [ [ WITH ] 
          [ BINARY ] 
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ] ]

COPY tablename [ ( column [, ...] ) ]
    TO { 'filename' | STDOUT }
    [ [ WITH ] 
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ] ]

説明

COPYコマンドは、PostgreSQL のテーブルと標準のファイルシステムのファイル間でデータを移動します。 COPY TO コマンドはテーブルのすべての内容をファイルコピーします。 また、COPY FROM コマンドは、ファイルからテーブルへとデータをコピーします (このとき、すでにテーブルにあるデータにコピー内容を追加します)。

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

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

パラメータ

tablename

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

column

省略可能な、コピーする列のリストです。 列のリストが指定されていない場合は、すべての列が使用されます。

filename

入出力ファイルの絶対パス名です。

STDIN

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

STDOUT

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

BINARY

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

OIDS

各行のOIDをコピーすることを指定します。 (OIDを持たないテーブルにOIDSを指定するとエラーが発生します。)

delimiter

ファイルの各行(ライン)の列を区切る一文字を指定します。 デフォルトはタブ文字です。

null string

NULL 値を表す文字列です。 デフォルトでは \N(バックスラッシュ N)です。 しかし、場合によっては、例えば、空の文字列の方がよいかもしれません。

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

注釈

COPY は通常のテーブルに対してのみ使用することができます。 ビューに対しては使用することができません。

BINARY キーワードはすべてのデータをテキストではなく、バイナリ書式として書き込み/読み込みするように指定します。 通常の COPY コマンドより多少速く動作しますが、バイナリ書式のファイルを異なるマシンアーキテクチャで使用することや他のバージョンの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 では、最初のエラーで処理を停止させます。 これは、COPY TO コマンドを実行している際には何ら問題はありませんが、COPY FROM の場合は、対象となるテーブルは始めのほうの行を受け取り済みです。 これらの行は見えませんし、アクセスすることもできませんが、ディスク領域を占有します。 大きなコピー処理に何度も失敗した場合には、無視できないほど無駄なディスク領域が増えてしまいます。 この無駄な領域を取り戻すために、VACUUM を行う必要があります。

ファイルの書式

テキスト書式

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

データの終了は、バックスラッシュ-ピリオド(\.) だけから構成される 1 行で表されます。 ファイルの終了によって、完全に同じ機能を提供することができますので、データ終了マークは、ファイルから読み込む際には不要です。 しかし、3.0以前のクライアントプロトコルを使用したクライアントアプリケーションへ、または、からのデータコピーの場合だけは、終了マークを与えなければなりません。

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

以下の特別なバックスラッシュから始まる文字の並びは、COPY FROM によって解釈されます。

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

現在、COPY TO は 8 進数数字のバックスラッシュ並びを出力することはありませんが、上記一覧に存在しない制御文字には、これを使用します。

N またはピリオド (.) というデータ文字の前には、バックスラッシュを決して付けないで下さい。 この組み合わせは、それぞれ、ヌル文字とデータ終了マークのデフォルトと間違って解釈されてしまいます。 上で示した以外のバックスラッシュ文字はそのまま解釈されます。

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

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

バイナリ形式

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

ファイルヘッダ

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

署名

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

フラグフィールド

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

ビット16

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

ヘッダ拡張領域長

32ビット整数であり、それ自身を含まない、ヘッダの残り部分のバイト長です。 現在、これは0で、すぐ後に最初のタプルが続きます。 今後、ヘッダ内に追加データを格納できるような書式の変更があるかもしれません。 読み込み先では、どのように扱うか分からない、全てのヘッダ拡張データを単に飛ばさなければなりません。

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

この設計は、後方互換性のあるヘッダの追加(ヘッダ拡張チャンクの追加や下位フラグビットの設定)と後方互換性のない変更(変更を知らせるための高位フラグビットの設定や必要に応じた拡張領域へのサポート情報追加)に有効です。

タプル

すべてのタプルはタプル内のフィールド数を表す16ビット整数から始まります(現時点では、テーブル内のすべてのタプルは同一のフィールド数を持つようになっていますが、常にそうであるとは限りません)。 その後に、タプル中のそれぞれのフィールドが、フィールドデータが何バイトあるかを表す32ビット長のワードの後に、繰り返し続きます。 (このバイト長ワードにはそれ自身は含まれず、0になることもあります。) 特殊な場合として、-1 はNULLフィールドを表す値です。 この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';

これは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' ]