Chr*_*ris 8 postgresql postgresql-9.2
我有一个多租户数据库设置,需要添加一些列。我正在使用模式(和 search_path)来划分我的用户,所以我正在寻找一种普遍存在的方法来将 DDL 模式更改应用于我的所有数据库。最初,我认为我可以将其作为单个查询(pg_catalog 上的光标)来执行,但认为命令行调用psql -f
可能是首选方式。
dez*_*zso 11
我更喜欢后一种解决方案。您可以将架构名称收集到以下文件中(每行一个架构)psql
:
\o change_schema.sql
\t on
SELECT n.nspname
FROM pg_catalog.pg_namespace n
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema';
-- reset the output
\o
\t off
Run Code Online (Sandbox Code Playgroud)
然后您可以轻松地执行以下操作:
有一个 DDL 更改脚本(例如,change_schema.sql
),而不参考包含架构
SET search_path TO :schema;
BEGIN;
...
...
ALTER TABLE orders
ADD COLUMN last_modified timestamp;
...
...
COMMIT;
Run Code Online (Sandbox Code Playgroud)
然后你可以把模式列表的每一行变成一行
psql -h dbhost -d targetdb -f change_schema.sql -v schema=<schema_name>
Run Code Online (Sandbox Code Playgroud)
sed
例如,使用一个简单的命令 - 那么你只需要运行这些命令。当然,如果您愿意,您可以将其转换为适当的 shell 脚本。
Cra*_*ger 10
为了完整起见,另一种方法是遍历所有模式并在 PL/PgSQL 中使用动态 SQL 运行更改,例如:
DO
$$
DECLARE
schemaname name;
BEGIN
FOR schemaname IN SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname <> 'information_schema' LOOP
EXECUTE format('ALTER TABLE %I.my_table ADD COLUMN blah blah;', schemaname);
END LOOP;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)