違うschemaに存在する、同じ構造のtableに対して、pg_dumpでデータを抽出/挿入する方法を記します。最初にオチを言うと、\COPYを使用したほうが楽です。
環境
- PostgreSQL
- 8.4.20
- CentOS
- 6.7
前提条件
下記の通り、test1.testからtest2.testに対してデータをコピーします。
postgres=# \dn
List of schemas
Name | Owner
--------------------+----------
information_schema | postgres
pg_catalog | postgres
pg_toast | postgres
pg_toast_temp_1 | postgres
public | postgres
test1 | postgres
test2 | postgres
(7 rows)
postgres=# \d test1.test
Table "test1.test"
Column | Type | Modifiers
--------+------+-----------
val | text |
postgres=# \d test2.test
Table "test2.test"
Column | Type | Modifiers
--------+------+-----------
val | text |
postgres=# select * from test1.test;
val
------------
testvalue1
testvalue2
testvalue3
(3 rows)
postgres=# select * from test2.test;
val
-----
(0 rows)
手順
対象テーブルに対して、pg_dumpをplainでダンプします。customで色々と試してみましたが、結局徒労に終わりました。
pg_dump --file=./test.dmp --format=p --data-only --table=test1.test
plainのため、中身はviで見ることができます。
-bash-4.1$ ll
total 12
drwx------. 2 postgres postgres 4096 Jun 29 08:59 backups
drwx------. 12 postgres postgres 4096 Oct 8 22:38 data
-rw-r--r--. 1 postgres postgres 463 Oct 8 23:06 test.dmp
-bash-4.1$ cat test.dmp
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;
SET search_path = test1, pg_catalog;
--
-- Data for Name: test; Type: TABLE DATA; Schema: test1; Owner: postgres
--
COPY test (val) FROM stdin;
testvalue1
testvalue2
testvalue3
\.
--
-- PostgreSQL database dump complete
--
スキーマが書かれている箇所を手で直してしまっても構いませんが、コマンドで自動化してしまいます。
sed -i.`date "+%Y%m%d-%H%M%S"` -e 's/test1/test2/g' test.dmp
念のため、diffで確認してみます。
diff test.dmp*
12c12
< SET search_path = test2, pg_catalog;
---
> SET search_path = test1, pg_catalog;
15c15
< -- Data for Name: test; Type: TABLE DATA; Schema: test2; Owner: postgres
---
> -- Data for Name: test; Type: TABLE DATA; Schema: test1; Owner: postgres
後は普通にpsqlで流し込みます。
psql --file=test.dmp
下記の通り確認してみます。成功です。
postgres=# select * from test2.test;
val
------------
testvalue1
testvalue2
testvalue3
(3 rows)
最後に
今回はpg_dumpにこだわってみたのですが、\COPYを使用するほうが楽だと思います。対象のテーブルをコマンド実行時に指定できますしね。