如何在PostgreSQL中复制模式

Cri*_*jon 16 postgresql foreign-key-relationship database-schema postgresql-9.1

我有一个架构public和数据库schema_A.我需要创建一个schema_b结构相同的新模式schema_a.我发现下面的函数,问题是它不复制外键约束.

CREATE OR REPLACE FUNCTION clone_schema(source_schema text, dest_schema text)
  RETURNS void AS
$BODY$
DECLARE
  object text;
  buffer text;
  default_ text;
  column_ text;
BEGIN
  EXECUTE 'CREATE SCHEMA ' || dest_schema ;

  -- TODO: Find a way to make this sequence's owner is the correct table.
  FOR object IN
    SELECT sequence_name::text FROM information_schema.SEQUENCES WHERE sequence_schema = source_schema
  LOOP
    EXECUTE 'CREATE SEQUENCE ' || dest_schema || '.' || object;
  END LOOP;

  FOR object IN
    SELECT table_name::text FROM information_schema.TABLES WHERE table_schema = source_schema
  LOOP
    buffer := dest_schema || '.' || object;
    EXECUTE 'CREATE TABLE ' || buffer || ' (LIKE ' || source_schema || '.' || object || ' INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING DEFAULTS)';

    FOR column_, default_ IN
      SELECT column_name::text, REPLACE(column_default::text, source_schema, dest_schema) FROM information_schema.COLUMNS WHERE table_schema = dest_schema AND table_name = object AND column_default LIKE 'nextval(%' || source_schema || '%::regclass)'
    LOOP
      EXECUTE 'ALTER TABLE ' || buffer || ' ALTER COLUMN ' || column_ || ' SET DEFAULT ' || default_;
    END LOOP;
  END LOOP;

END;
$BODY$  LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

如何克隆/复制schema_A外键约束?

use*_*922 24

您可以在不使用文件的情况下从命令行执行此操作:

pg_dump -U user --schema='fromschema' database | sed 's/fromschmea/toschema/g' | psql -U user -d database

请注意,这会搜索并替换作为架构名称的所有字符串,因此可能会影响您的数据.


Erw*_*ter 14

我会pg_dump用来转储没有数据的架构:

-s
--schema-only
Run Code Online (Sandbox Code Playgroud)

仅转储对象定义(架构),而不转储数据.

此选项与之相反--data-only.它类似于,但由于历史原因不完全相同,指定--section=pre-data --section=post-data.

(不要将此--schema选项与使用"schema"一词的选项混淆.)

要仅为数据库中的表子集排除表数据,请参阅--exclude-table-data.

pg_dump $DB -p $PORT -n $SCHEMA -s -f filename.pgsql
Run Code Online (Sandbox Code Playgroud)

然后重命名转储中的架构(搜索和替换)并将其还原psql.

psql $DB -f filename.pgsql
Run Code Online (Sandbox Code Playgroud)

引用其他模式中的表的外键约束将复制为指向同一模式.
同一模式中的表的引用指向复制的模式中的相应表.


Ada*_*dam 7

我将为我的问题分享一个解决方案,该解决方案与一个小补充相同。我需要克隆一个模式,创建一个新的数据库用户并将新模式中所有对象的所有权分配给该用户。

对于以下示例,我们假设参考架构称为ref_schema,目标架构称为new_schema。引用模式和其中的所有对象都归名为ref_user的用户所有

1. 使用 pg_dump 转储参考模式:

pg_dump -n ref_schema -f dump.sql database_name
Run Code Online (Sandbox Code Playgroud)

2. 创建一个名为new_user的新数据库用户:

CREATE USER new_user
Run Code Online (Sandbox Code Playgroud)

3. 将架构ref_schema重命名为new_schema

ALTER SCHEMA ref_schema RENAME TO new_schema
Run Code Online (Sandbox Code Playgroud)

4. 将重命名模式中所有对象的所有权更改为新用户

REASSIGN OWNED BY ref_user TO new_user
Run Code Online (Sandbox Code Playgroud)

5.从转储中恢复原始参考模式

psql -f dump.sql database_name
Run Code Online (Sandbox Code Playgroud)

我希望有人觉得这有帮助。


rab*_*itt 6

虽然有点晚了,但是这里的一些 sql 可以帮助你:

获取模式 oid:

namespace_id = SELECT oid 
                  FROM pg_namespace 
                 WHERE nspname = '<schema name>';
Run Code Online (Sandbox Code Playgroud)

获取表的 oid:

table_id = SELECT relfilenode 
                FROM pg_class 
               WHERE relnamespace = '<namespace_id>' AND relname = '<table_name>'
Run Code Online (Sandbox Code Playgroud)

获取外键约束:

SELECT con.conname, pg_catalog.pg_get_constraintdef(con.oid) AS condef 
  FROM pg_catalog.pg_constraint AS con 
  JOIN pg_class AS cl ON cl.relnamespace = con.connamespace AND cl.relfilenode = con.conrelid 
 WHERE con.conrelid = '<table_relid>'::pg_catalog.oid AND con.contype = 'f';
Run Code Online (Sandbox Code Playgroud)

可以在此处找到有关 PostgreSQL 系统表的优质资源。此外,您可以通过查看源代码pg_dump来了解有关收集转储信息的内部查询的更多信息。

了解如何pg_dump收集所有数据的最简单方法可能是strace对其进行使用,如下所示:

$ strace -f -e sendto -s8192 -o pg_dump.trace pg_dump -s -n <schema>
$ grep -oP '(SET|SELECT)\s.+(?=\\0)' pg_dump.trace
Run Code Online (Sandbox Code Playgroud)

您仍然需要对大量语句进行排序,但是,它应该可以帮助您以编程方式拼凑出克隆工具,并避免必须转到 shell 来调用pg_dump.

  • 这是我刚刚编写的一个 python 类,它使用所有 SQL 来执行模式克隆(包括数据复制),并且不使用 pg_dump:[https://gist.github.com/rabbitt/97f2c048d9e38c16ce62](https://gist. github.com/rabbitt/97f2c048d9e38c16ce62) (3认同)