Postgresのデータベース間でテーブルをコピーする


273

Postgresで1つのデータベースから別のデータベースにテーブル全体をコピーしようとしています。助言がありますか?


1
DBeaverのインストールに問題がなければ、接続している2つのデータベース間を転送する非常に簡単な方法があります。ソーステーブルを右クリックして[データのエクスポート]を選択し、データベーステーブルをターゲットにして、ターゲットをターゲットデータベースとして設定します。
rovyko

回答:


311

テーブルを抽出し、ターゲットデータベースに直接パイプします。

pg_dump -t table_to_copy source_db | psql target_db

注:他のデータベースですでにテーブルが設定されている場合は、-aフラグを使用してデータのみをインポートする必要があります。そうしないと、「メモリ不足」のような奇妙なエラーが表示される場合があります。

pg_dump -a -t my_table my_db | psql target_db

5
これは、remote-dbリンクに対してどのように機能しますか?たとえば、別の場所からダンプする必要があります。
curlyreggie、2014年

17
@curlyreggieはこれを試しませんでしたが、うまくいかない理由はわかりません。次のように、ユーザーとサーバーの詳細をコマンドに追加してみてくださいpg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax

2
これを試すことができます: "pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db -U remote_user -h remote_server"
Hua Zhang

18
他のデータベースですでにテーブルが設定されている場合は、-aフラグをデータのみに使用する必要があることに注意してください。すなわちpg_dump -a -t my_table my_db | psql target_db。ここにいる間、データベースがサーバー上にある場合は、データベースをファイルにダンプし、そのファイルをデータベースにscpし、ファイルの内容をpsqlに送信する方が簡単だと思います。たとえばpg_dump -a -t my_table my_db > my_file.sql、それをサーバーに配置した後->psql my_other_db < my_file.sql
Nick Brady

3
@EamonnKennyは大文字と小文字を区別するテーブルをダンプしますpg_dump -t '"tableToCopy"' source_db | psql target_db。単一引用符と二重引用符は、テーブル名を囲むことに注意してください
ギラッドmayani

105

pgAdmin IIのバックアップ機能を使用することもできます。次の手順に従ってください。

  • pgAdminで、移動するテーブルを右クリックし、[バックアップ]を選択します
  • 出力ファイルのディレクトリを選択し、フォーマットを「プレーン」に設定します
  • 「ダンプオプション#1」タブをクリックし、「データのみ」または「スキーマのみ」をチェックします(何をしているのかに応じて)
  • [クエリ]セクションで、[列の挿入を使用]と[ユーザー挿入コマンド]をクリックします。
  • 「バックアップ」ボタンをクリックします。これは.backupファイルに出力します
  • メモ帳を使用してこの新しいファイルを開きます。テーブル/データに必要な挿入スクリプトが表示されます。これらをコピーして、pgAdminの新しいデータベースSQLページに貼り付けます。pgScriptとして実行-クエリ-> pgScript F6として実行

うまく機能し、一度に複数のテーブルを実行できます。


1
これは、データベース間でデータを移動するためのGUIベースの優れたソリューションです。ありがとう!
kgx 2013年

3
Objectsセクションの下で複数のテーブルを選択できます。OSXでは、SQLボタンをクリックするかSQL EditorToolsメニューから取得して、バックアップファイルからコピーしたSQLを貼り付けます。
Aleck Landgraf 2013

作品、ありがとう。大きなテーブルでは非常に遅いですが、速度を上げるためのより良い方法はありますか?(外部キーなどを無視するようなものですか?)
TimoSolo

3
@Timothy バックアップと復元を高速化する方法についてのpostgresのドキュメントページは次のとおりです
laurie

古い回答ですが、関連性はありますが、うまく機能します。すべてのデータベースをエクスポートするときに、無効化トリガーを設定することを忘れないでください
norbertas.gaulia

75

dblink使用する方が便利です。

truncate table tableA;

insert into tableA
select *
from dblink('dbname=postgres hostaddr=xxx.xxx.xxx.xxx dbname=mydb user=postgres',
            'select a,b from tableA')
       as t1(a text,b text);

12
なぜ2つのdbnameが2回に..?どちらがソースとターゲットです。
arulraj.net 2014

1
挿入先のtableAが宛先で、dbLinkのtableAがソースです。
aggietech 2015

dblink bunを使用する場合、ソースソーステーブルの構造がわかりません。
Ossarotte

31

両方のサーバーに接続できるLinuxホストでのpsqlの使用

( export PGPASSWORD=password1 
  psql -U user1 -h host1 database1 \
  -c "copy (select field1,field2 from table1) to stdout with csv" ) \
| 
( export PGPASSWORD=password2 
  psql -U user2 -h host2 database2 \ 
   -c "copy table2 (field1, field2) from stdin csv" )

エクスポートの必要はありません PGPASSWORD=password1 psql -U ...。明示的なサブシェルも必要ありません。通常、最初にセットアップするにはいくつかのことを行う必要があるため、とにかくサブシェルが必要になる場合があります。また、パスワードは後続のプロセスにエクスポートされません。ありがとう!
限定的な償い

1
@LimitedAtonement実際、あなたは正しい、エクスポートとサブシェルは必要ありません。これはより複雑なスクリプトの一部であり、エクスポートとサブシェルなしで試したわけでもないので、正直に言って、効果的なソリューションを提供します
Alexey Sviridov

テーブルは宛先DBに存在している必要があります。それを作成するには、試してくださいpg_dump -t '<table_name>' --schema-only
fjsj

24

最初にdblinkをインストールします

次に、次のようなことを行います。

INSERT INTO t2 select * from 
dblink('host=1.2.3.4
 user=*****
 password=******
 dbname=D1', 'select * t1') tt(
       id int,
  col_1 character varying,
  col_2 character varying,
  col_3 int,
  col_4 varchar 
);

1
コピーされた行をフィルタリングできるため、この回答は素晴らしいです(dblinkの2番目の引数にWHERE句を追加します)。ただし、次のような列名(Postgres 9.4)を明示する必要がありますINSERT INTO l_tbl (l_col1, l_col2, l_col3) SELECT * FROM dblink('dbname=r_db hostaddr=r_ip password=r_pass user=r_usr', 'select r_col1, r_col2, r_col3 from r_tbl where r_col1 between ''2015-10-29'' AND ''2015-10-30'' ') AS t1(col1 MACADDR, col2 TIMESTAMP, col3 NUMERIC(7,1));(lはローカルを意味し、rはリモートです。単一引用符をエスケープします
。col

14

pg_dumpを使用してテーブルデータをダンプし、psqlで復元します。


2
次に、別のデータベースロールを使用して接続します。これは、十分な権限を持つロールです。postgresql.org/docs/8.4/static/app-pgdump.html
フランクハイケンズ

何が悪いのですか?pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres"は、ロールを設定しようとしているユーザーです。それでも「アクセスが拒否されました」と表示されます。
nix

db.sqlファイルを書き込む権限がありますか?
10

自分が持っている権限を確認するにはどうすればよいですか?
nix

このスレッドは古いですが、問題を抱えている他の人にとっては、PgAdminIIIの「ツール->バックアップ」メニューを使用してみてください。これは、権限の問題を回避しているようです。
ジョン

13

あなたが両方のリモートサーバーを持っているなら、あなたはこれに従うことができます:

pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase

すでに既存のスキーマがある場合は、前述のソースデータベースのテーブルをターゲットデータベースの同じ名前のテーブルにコピーします。



8

ここに私のために働いたものがあります。最初にファイルにダンプします。

pg_dump -h localhost -U myuser -C -t my_table -d first_db>/tmp/table_dump

次に、ダンプされたファイルをロードします。

psql -U myuser -d second_db</tmp/table_dump

ダンプロードには "-h localhost"も必要です
DTukans 2017年

6

ローカル設定でデータベースAからデータベースBにテーブルを移動するには、次のコマンドを使用します。

pg_dump -h localhost -U owner-name -p 5432 -C -t table-name database1 | psql -U owner-name -h localhost -p 5432 database2

私はそれを試してみました。最初のパスワードしか指定できないため、これは機能しません。
最大

1
export PGPASSWORD=<passw>コマンドを実行する前に実行できる@max
lukaszzenko

4

ここでいくつかの解決策を試しましたが、それらは本当に役に立ちました。私の経験では、psqlコマンドラインを使用することが最善の解決策ですが、psqlコマンドラインを使用したくない場合もあります。だからここにpgAdminIIIの別のソリューションがあります

create table table1 as(
 select t1.* 
 from dblink(
   'dbname=dbSource user=user1 password=passwordUser1',
   'select * from table1'  
  ) as t1(
    fieldName1 as bigserial,
    fieldName2 as text,
    fieldName3 as double precision 
  )
 )

この方法の問題は、コピーするフィールドの名前とテーブルのタイプを記述する必要があることです。


4

pg_dump 常に機能するとは限りません。

両方のデータベースに同じテーブルddlがある場合、次のようにstdoutとstdinからハッキングできます。

 # grab the list of cols straight from bash

 psql -d "$src_db" -t -c \
 "SELECT column_name 
 FROM information_schema.columns 
 WHERE 1=1 
 AND table_name='"$table_to_copy"'"
 # ^^^ filter autogenerated cols if needed     

 psql -d "$src_db" -c  \
 "copy ( SELECT col_1 , col2 FROM table_to_copy) TO STDOUT" |\
 psql -d "$tgt_db" -c "\copy table_to_copy (col_1 , col2) FROM STDIN"

3

user5542464およびPiyush S. Wanareによる回答と同じですが、2つのステップに分かれます。

pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase > dump
cat dump | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase

それ以外の場合、パイプは2つのパスワードを同時に要求します。


ターゲットデータベースのテーブル名について言及できる可能性はありますか?
Piyush S. Wanare

2

DbLinkを使用して、1つのテーブルデータを別のデータベースの別のテーブルにコピーする必要があります。データベース間のクエリを実行するには、DbLink拡張機能をインストールして構成する必要があります。

このトピックに関する詳細な投稿はすでに作成しています。 このリンクにアクセスしてください


2

このpythonスクリプトを確認してください

python db_copy_table.py "host=192.168.1.1 port=5432 user=admin password=admin dbname=mydb" "host=localhost port=5432 user=admin password=admin dbname=mydb" alarmrules -w "WHERE id=19" -v
Source number of rows = 2
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister1',true,false);
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister2',true,false);

1

両方のDB(from&to)がパスワードで保護されている場合、そのシナリオでは、ターミナルは両方のDBのパスワードを要求しません。パスワードプロンプトは1回だけ表示されます。したがって、これを修正するには、コマンドとともにパスワードを渡します。

PGPASSWORD=<password> pg_dump -h <hostIpAddress> -U <hostDbUserName> -t <hostTable> > <hostDatabase> | PGPASSWORD=<pwd> psql -h <toHostIpAddress> -d <toDatabase> -U <toDbUser>

1

DataGrip(Intellij Idea)を使用していました。あるテーブルから(別のデータベースにある)別のテーブルにデータをコピーするのは非常に簡単でした。

まず、データグリップで両方のデータソースに接続していることを確認します。

ソーステーブルを選択し、F5キーを押すか、または(右クリック-> [テーブルのコピー先を選択]をクリックします。)

これにより、すべてのテーブルのリストが表示されます(ポップアップウィンドウでテーブル名を使用して検索することもできます)。ターゲットを選択してOKを押してください。

DataGripは他のすべてを処理します。


2
注意してください、DataGripは無料ではありません
Rahmat Ali

0

WindowsからpgAdmin(バックアップ:pg_dump、復元:)を実行pg_restoreするc:\Windows\System32と、デフォルトでにファイルを出力しようとします。そのため、ユーザーpostgresが十分に昇格されていないためではなく、アクセス許可/アクセス拒否エラーが発生します。pgAdminを管理者として実行するか、Windowsのシステムフォルダー以外の出力の場所を選択します。


0

別の方法として、外部データラッパー拡張を使用して、リモートテーブルをローカルテーブルとして公開することもできます。その後、リモートデータベースのテーブルから選択して、テーブルに挿入できます。唯一の欠点は、あまり速くないことです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.