如何在psql中使用外键约束将一个表的结构复制到另一个表?

时间:2014-05-16 06:25:46

标签: postgresql foreign-keys plpgsql create-table

使用

时不会复制外键约束
create table table_name ( like source_table INCLUDING ALL)' 
在Postgres中。如何创建现有表的副本,包括所有外键。

2 个答案:

答案 0 :(得分:17)

没有选项可以在CREATE TABLE ... LIKE ...中自动创建外键。

the documentation:

  

LIKE source_table [like_option ...]

     

始终将非空约束复制到新表中。校验   只有在指定了INCLUDING CONSTRAINTS [...]

时才会复制约束      

原始表上的索引,PRIMARY KEY和UNIQUE约束   只有在INCLUDING INDEXES子句中才会在新表上创建   已指定。

在实践中,使用GUI工具很容易。例如,在PgAdmin III中:

  • source_table的复制声明(DDL)到查询工具(ctrl-e),
  • 编辑声明,
  • 执行sql。

在SQL脚本中,您可以使用以下功能。重要的假设:源表外键具有正确的名称,即它们的名称包含源表名称(典型情况)。

create or replace function create_table_like(source_table text, new_table text)
returns void language plpgsql
as $$
declare
    rec record;
begin
    execute format(
        'create table %s (like %s including all)',
        new_table, source_table);
    for rec in
        select oid, conname
        from pg_constraint
        where contype = 'f' 
        and conrelid = source_table::regclass
    loop
        execute format(
            'alter table %s add constraint %s %s',
            new_table,
            replace(rec.conname, source_table, new_table),
            pg_get_constraintdef(rec.oid));
    end loop;
end $$;

使用示例:

create table base_table (base_id int primary key);
create table source_table (id int primary key, base_id int references base_table);

select create_table_like('source_table', 'new_table');

\d new_table

   Table "public.new_table"
 Column  |  Type   | Modifiers 
---------+---------+-----------
 id      | integer | not null
 base_id | integer | 
Indexes:
    "new_table_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "new_table_base_id_fkey" FOREIGN KEY (base_id) REFERENCES base_table(base_id)

答案 1 :(得分:1)

还有一种方法是转储表结构,在转储中更改它的名称,然后重新加载它:

pg_dump -s -t old databases | sed 's/old/new/g' | psql