gpt4 book ai didi

sql - 包含序列的重复 postgresql 模式

转载 作者:行者123 更新时间:2023-11-29 11:23:51 30 4
gpt4 key购买 nike

我的数据库布局需要为每个新客户创建新模式。目前我使用在网上找到的内部函数并稍微修改。

CREATE FUNCTION copy_schema(
source_schema character varying,
target_schema character varying,
copy_data boolean)
RETURNS integer AS
$BODY$
DECLARE
t_ex integer := 0;
s_ex integer := 0;
src_table character varying;
trg_table character varying;
BEGIN
if (select 1 from pg_namespace where nspname = source_schema) THEN
-- we have defined target schema
s_ex := 1;
END IF;

IF (s_ex = 0) THEN
-- no source schema exist
RETURN 0;
END IF;

if (select 1 from pg_namespace where nspname = target_schema) THEN
-- we have defined target schema need to sync all table layout
t_ex := 1;
ELSE
EXECUTE 'CREATE SCHEMA '||target_schema||' AUTHORIZATION user';
END IF;

FOR src_table IN
SELECT table_name
FROM information_schema.TABLES
WHERE table_schema = source_schema
LOOP
trg_table := target_schema||'.'||src_table;
EXECUTE
'CREATE TABLE ' || trg_table || ' (LIKE ' || source_schema || '.' || src_table || ' INCLUDING ALL)';
IF (copy_data = true) THEN
EXECUTE 'INSERT INTO ' || trg_table || '(SELECT * FROM ' || source_schema || '.' || src_table || ')';
END IF;
END LOOP;

return t_ex;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

此脚本的问题是新模式中的表继续使用源模式的序列。有没有办法使用 sql 语句(或其他可靠的方法)为新创建的表获取序列的新副本(或者甚至是复制整个模式的另一种可靠方法)?

最佳答案

问题的根源

与旧序列的连接来自所涉及列的普通默认值。我引用 the manual here :

Default expressions for the copied column definitions will only be copied if INCLUDING DEFAULTS is specified. The default behavior is to exclude default expressions, resulting in the copied columns in the new table having null default.

由于您使用

创建了新表
INCLUDING ALL

和:

INCLUDING ALL is an abbreviated form of INCLUDING DEFAULTS INCLUDING
CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS
.

.. 你得到相同的默认值。您可以在创建新表后排除默认值或显式更改默认值,包括 nextval()。我认为没有任何中间立场。


转储/破解转储/恢复更简单

or even another reliable way to duplicate entire schema

您可以使用 pg_dump 转储模式的模式(同一个词,不同的含义):

pg_dump $DB -p $PORT -n $SCHEMA -sf /var/lib/postgresql/your_name.pgsql

破解转储(意思是:在转储上使用文本编辑器,或编写脚本):交换转储顶部的架构名称,以及 SET search_path 中的所有其他事件,并作为架构-序列资格甚至更多。如果您为架构选择了一个唯一名称,则运行一次全局搜索并用您喜欢的工具(sedvim 或.. .) 应该完成这项工作。

然后使用 psql 对同一个或任何其他数据库运行 SQL 脚本:

psql $DB -p $PORT -f /var/lib/postgresql/your_name.pgsql > /dev/null

与我最初发布的内容相反,串行列在转储中仍然分开(至少在 PostgreSQL 9.1.5 中)。 SQL 脚本单独创建序列,将它们附加到序列列:

ALTER SEQUENCE seq OWNED BY tbl.col;

并单独设置默认值。

顺便说一句:当前版本的 pgAdmin 在满足所有要求时对 DDL 脚本中的 serial 列进行逆向工程。

关于sql - 包含序列的重复 postgresql 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12572088/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com