初めに
Qiita Engineer Festa 2024に参加中。完走目指してます。
他のメタコマンドについては以下から読んでください。
\copyとは
フロントエンド(クライアント)コピーを行います。 これは
COPY
SQLコマンドを実行する操作ですが、サーバで指定ファイルに対する読み込みまたは書き込みを行うのではなく、psqlがファイルの読み書きや、サーバとローカルファイルシステム間のデータ送信を行います。 この場合、ファイルへのアクセス権限はサーバではなくローカルユーザのものを使用するので、SQLのスーパーユーザ権限は必要ありません。
program
が指定された場合、command
がpsqlにより実行され、command
から、または、command
へのデータはサーバとクライアント間を行き来します。 ここでも、実行権限はローカル側のユーザであり、サーバ側ではなく、SQLスーパーユーザ権限は必要とされません。
\copy ... from stdin
では、データ行は、コマンドの発行源と同じところから、\.
を読み取るまで、あるいは、ストリームがEOFに達するまで読み続けます。 このオプションは、SQLスクリプトファイルの内部でテーブルにデータを投入する場合に便利です。\copy ... to stdout
では、出力はpsqlコマンドの出力と同じところに送られますが、COPY count
コマンドのステータスは表示されません(これはデータ行と混同してしまうかもしれないからです)。 コマンドの入力元や\o
オプションに関わらず、psqlの標準入力や標準出力を読み書きするには、from pstdin
あるいはto pstdout
と書いてください。このコマンドの構文はSQLの
COPY
コマンドに似ています。 データの入力元と出力先以外のすべてのオプションはCOPY
と同じです。 このため\copy
メタコマンドには特別な解析規則が適用されていることに注意してください。 他のほとんどのメタコマンドとは異なり、行の残り部分の全体は常に\copy
の引数として解釈され、引数内の変数の置換や逆引用符の展開は行われません。
試してみた
検証用のテーブルを作成しデータを投入する
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name TEXT,
age INTEGER,
department TEXT
);
INSERT INTO employees (name, age, department) VALUES
('John Doe', 30, 'HR'),
('Jane Smith', 25, 'IT'),
('Sam Brown', 35, 'Finance');
テーブルのデータをファイルにコピーする
postgres=# \copy employees TO 'employees.csv' WITH (FORMAT CSV, HEADER);
COPY 3
lessなどでファイルが作成されてデータもコピーされていることを確認する
一度テーブル内のデータを削除する
postgres=# delete from employees;
DELETE 3
postgres=# select * from employees;
id | name | age | department
----+------+-----+------------
(0 行)
ファイルのデータをテーブルにコピーする
postgres=# \copy employees FROM 'employees.csv' WITH (FORMAT CSV, HEADER);
COPY 3
selectで確認
postgres=# select * from employees;
id | name | age | department
----+------------+-----+------------
1 | John Doe | 30 | HR
2 | Jane Smith | 25 | IT
3 | Sam Brown | 35 | Finance
(3 行)
まとめ
データのdumpファイルを見てみるとcopyコマンドが使われているのもあって大量データのインポート・エクスポートに対してはcopyコマンドの方が効率良さそうです。
これについては別途具体的になぜ効率的なのかは調べたいですね。