2017-05-15 13 views
1

すべてのテーブルを作成してローカルテストの実行時間を短縮したいUNLOGGED。私はすべての変換の後に実行してUNLOGGEDにするSQLスクリプトを書いてみたいです。しかし、問題テーブルがFKであることがわかったので、postgresqlはUNLOGGEDではないテーブルと関連していれば、テーブルUNLOGGED(〜ALTERまで)を作ることを禁止します。データベース内のすべてのテーブルをUNLOGGEDにする

ALTERを正しい順序でリストするのが良い方法はありますか?150を超えるテーブルがありますか?たとえば、データベースレベルで適用します。

+0

、;もちろん

select format('alter table %I.%I drop constraint %I cascade;', ns.nspname, tb.relname, c.conname) as ddl from pg_constraint c join pg_class tb on tb.oid = c.conrelid join pg_namespace ns on ns.oid = tb.relnamespace where ns.nspname not in ('pg_catalog', 'information_schema') and ns.nspname not like 'pg_temp%' and c.contype in ('f'); 

をあなたがそれらをドロップ前FKSにを生成するためのクエリを実行する必要があります。そして、

select format('alter table %I.%I add constraint %I ', ns.nspname, tb.relname, conname)|| pg_get_constraintdef(c.oid, true)||';' as ddl from pg_constraint c join pg_class tb on tb.oid = c.conrelid join pg_namespace ns on ns.oid = tb.relnamespace where ns.nspname not in ('pg_catalog', 'information_schema') and ns.nspname not like 'pg_temp%' and c.contype in ('f') 

すべての制約を削除するスクリプトを生成私はすべてのテーブルを未記録にすることができましたが、テストの実行は〜20%遅くなりました。だから、それをしないでください。 – mshutov

答えて

1

あなたは正しい順序でそれらを変更する必要があります私は恐れています。あなたは最初のテーブルを参照するためhttps://www.postgresql.org/docs/current/static/catalog-pg-constraint.htmlとループを選択し、残りの部分を変更することができ :

t=# create table s134(i int primary key, e int); 
CREATE TABLE 
t=# create table s135(i int references s134(i), e int primary key); 
CREATE TABLE 
t=# alter table s134 add constraint c1 foreign key (e) references s135(e); 
ALTER TABLE 
t=# alter table s134 set unlogged; 
ERROR: could not change table "s134" to unlogged because it references logged table "s135" 
t=# alter table s135 set unlogged; 
ERROR: could not change table "s135" to unlogged because it references logged table "s134" 

をしかし、あなたはどんなことを達成できないだろう:すべてのことで

begin; 
do 
$$ 
declare 
_r record; 
_t text; 
begin 
for _r in (
    select relname,conrelid 
    from pg_constraint 
    join pg_class c on c.oid = conrelid 
    where confkey is not null 
    order by conrelid desc 
    -- Order by oid with logic that you should start from latest added objects to earliest - of course it does not garantee anything 
) loop 
    _t := format('alter table %I set unlogged',_r.relname); 
    raise info '%',_t; 
    execute _t; 
end loop; 

    for _r in (select tablename from pg_tables where tablename like 's%' and schemaname = 'public') loop 
    _t := format('alter table %I set unlogged',_r.tablename); 
    raise info '%',_t; 
    execute _t; 
end loop; 

end; 
$$ 
; 
rollback; 

あなたは、再帰的なFKに持っている場合、それは失敗を意味します私は信じています。

また、不正なシャットダウンまたは障害が発生した後に、未ログインのテーブルが切り捨てられることを忘れないでください。

そして最後に、あなたは「すべての変換の後に」と言う - あなたが作成した場合などに変換、多分あなただけのログに記録されないそれらを作成する必要があります。..

+0

ありがとうございます。私の環境でこの解決策を試してみる 変換について - DBスキームが開発環境、テスト環境、およびプロダクト環境で同等であることを保証するために、本番環境とテスト環境の両方で実行されます。また、テストDB内のテーブルは、各テストの前に完全に変換されるので、破損は問題ではありません。 – mshutov

+0

は理にかなっています - 私は郵便から明らかではなく、奇妙なようでした:) udachi! –

+0

あなたのコメント 'について - 最新の追加されたオブジェクトから最も早いものから始めるべきであるという論理を持つoidによる注文 - もちろん何も保証していません。最後に、私は声明を印刷し、それらを並べ替えました。 残念ながら、テストの実行が〜20%遅くなりました – mshutov

1

私はすべての外部キーを削除して再作成するのでしょうか?。これを自動化することができます。

次のクエリは、すべての外部キーに対して必要なDDL文を生成します。その出力をファイルに保存する必要があります。このファイルを後ですべての外部キーを復元するために使用できます。すべての試験の後)

+0

ありがとうございます。興味深いアプローチ。それも試してみる。 – mshutov

+0

VaoTsunバリエーションを使用しました。適用が簡単だったためです。残念ながら、改善はありません – mshutov

関連する問題