【问题标题】:How to copy structure of one table to another with foreign key constraints in psql?如何在 psql 中使用外键约束将一个表的结构复制到另一个表?
【发布时间】:2014-07-04 19:46:00
【问题描述】:

使用时不复制外键约束

create table table_name ( like source_table INCLUDING ALL)' 

在 Postgres 中。如何创建包含所有外键的现有表的副本。

【问题讨论】:

    标签: postgresql foreign-keys plpgsql create-table


    【解决方案1】:

    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)
    

    【讨论】:

      【解决方案2】:

      另一种方法是转储表结构,在转储中更改其名称,然后再次加载:

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

      【讨论】:

      • 问题可能是创建一个表形式已经存在的表,具有相同的模式和约束形式 sql。
      • pg_dump -s -t old databases 不会包含外键约束
      猜你喜欢
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 2012-10-11
      • 2021-08-24
      • 1970-01-01
      相关资源
      最近更新 更多