違う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を使用するほうが楽だと思います。対象のテーブルをコマンド実行時に指定できますしね。