2016-04-30 18 views
0

PostgreSQL 9.2.8を使用して、あるデータベースのデータを別のデータベースに復元しようとしていますが、引き続きトリガが実行されているようです。コピーを行うために、以下に示すスクリプトを書いた。pg_restoreがトリガを無効にしていません

基本的に私の生産データベースにはdtsがあり、開発データベースにはDigitalTrafficSystemがあります。テーブルの構造は同じですが、devには非常に異なるストアドプロシージャがあります。

リストアを実行すると、DigitalTrafficSystemデータベースにはdtsデータベースに存在しないテーブル行が余分に残ってしまいます。そのため、トリガーによって作成されていると仮定しています。

私は、トリガーに関連する取得のメッセージは、各テーブルのために、そのように見える:

pg_restore: [archiver (db)] could not execute query: ERROR: permission denied: "RI_ConstraintTrigger_c_136691" is a system trigger 
Command was: ALTER TABLE usage ENABLE TRIGGER ALL; 

私はトリガーがオフになっていることを仮定しているが、ちょうどそのシステム・レベルのトリガはできなかった(誤って?)無効になります。トリガがオフになっているが、ちょうどその システム・レベルのトリガが無効に得ることができなかったことを

#!/bin/sh 

PGUSER=dts 
FILE=/tmp/.dts.db.$$ 

# Dump the schema of the DB as we want this to keep 
pg_dump -s DigitalTrafficSystem -f $FILE 

dropdb -U _postgres DigitalTrafficSystem 
if [ $? -ne 0 ]; then 
    exit; 
fi 

createdb -U _postgres -O dts DigitalTrafficSystem 
if [ $? -ne 0 ]; then 
    exit; 
fi 

# Restore the schema 
psql -d DigitalTrafficSystem -f $FILE 

# Dump the data of the real production database 
pg_dump -Fc -a dts -f $FILE > /dev/null 
if [ $? -ne 0 ]; then 
    exit; 
fi 

# Restore only the data from the real database to our development one 
pg_restore -a -d DigitalTrafficSystem --disable-triggers -S dts $FILE 

rm $FILE 
+0

これは間違いなくトリガーです。最後のpg_restoreを実行してデータベースを開き、すべてのトリガを手動で削除してから、pg_restoreコマンドを実行したところ、無効なデータが表示されませんでした。データベースを書き直すたびに手動で行うことはできません。 – Gargoyle

+0

空のデータベース(新しく作成され、テーブルを含まない)に--data-onlyリストアを実行しようとしているようですが、テーブル定義もターゲットDBに必要ですが、存在しないテーブル。 – wildplasser

+0

何らかの理由で、 'psql -d DigitalTrafficSystem -f $ FILE'でコピーできませんでした。データベースが作成された後に実行され、ダンプされたスキーマに基づいてリストアされます。 – Gargoyle

答えて

0

私は(間違って?)と仮定しています:

は、ここに私のスクリプトです。

いいえ、SQLコマンドの成功はすべてかどうかの問題です。失敗したコマンドは、おそらく形式のです:半分の仕事をしているとは対照的に、

ALTER TABLE usage DISABLE TRIGGER ALL; 

、それが失敗した場合、それはユーザレベルのトリガーを無効にし、RI-制約を残しされるであろう、完全に失敗します。トリガーを有効にします。

 Presently, the commands emitted for --disable-triggers must be done 
     as superuser. So you should also specify a superuser name with -S 
     or, preferably, run pg_restore as a PostgreSQL superuser. 

-S username, --superuser=username 
     Specify the superuser user name to use when disabling triggers. 
     This is relevant only if --disable-triggers is used. 

しかし、あなたのdtsはスーパーユーザではありません。

pg_restoreドキュメントは述べています。スクリプトの残りの部分によれば、_postgresはスーパーユーザーであるようです。その場合、-Sに渡すのはなぜですか?

コメントの@wildplasser notesのように、スクリプトはデータベースを作成してすぐにデータのみのインポートを実行するため、新しいデータベースのトリガーに気を配ってもおかしくないことがあります。これらのオブジェクトを含むデータベースは、これらのトリガーを使用してtemplate1と仮定できますか? しかし、template1のテーブルのデータも新しく作成されたデータベースにインポートされるため、ダンプのソースとデスティネーションデータベースの最終結果の間にある追加行についても考慮する必要があります。

+0

-S引数に_postgresを渡すと、セッション認可を設定する権限が拒否されました。 – Gargoyle

+0

@Gargoyle:私はこの文書の助言に従うと思う:_preferably、PostgreSQLのスーパーユーザーとしてpg_restoreを実行する –

+0

OK、私は 'psql -U _postgres DigitalTrafficSystem'を実行した場合、' alter user dts SUPERUSER'を実行できたエラーなしで実行されます。ありがとう! – Gargoyle

関連する問題