将数据库中的所有表设为 UNLOGGED

msh*_*tov 8 postgresql

我想通过制作所有表来减少本地测试执行时间UNLOGGED。我想编写sql脚本,它将在所有转换后运行并使它们成为UNLOGGED. 但我发现问题 - 表与 相互关联FK,因此如果它与其他尚未关联的表相关,则postgresql 禁止创建表UNLOGGED(通过) 。ALTERUNLOGGED

有没有更好的方法然后按ALTER正确的顺序列出所有内容 - 我有超过 150 张桌子?例如,将其应用在数据库级别。

Vao*_*sun 2

恐怕你必须按正确的顺序更改它们。您可以选择https://www.postgresql.org/docs/current/static/catalog-pg-constraint.html并首先循环引用表,然后更改其余部分:

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;
Run Code Online (Sandbox Code Playgroud)

如果你有递归 FK,无论如何它都会失败:

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"
Run Code Online (Sandbox Code Playgroud)

但我相信无论怎样你都无法实现这一目标。

另外不要忘记,在不正常关闭或失败后,未记录的表将被截断。

最后你说“在所有转换之后” - 如果你创建、转换等,也许你应该只创建它们不记录?...