Postgres针对多个模式运行语句

时间:2017-03-02 14:53:28

标签: postgresql

我有一个多租户应用程序,其中租户在同一数据库中的不同模式上设置。原因是他们在其中一个模式上使用了一些共享数据。

到目前为止,我一直在使用bash脚本,其中包含其中的模式列表,每当添加新模式时我都需要更新这些模式,并且我需要在帐户中执行表模式更改等操作。例如,向表中添加新列。

在Postgres,psql等中是否有办法运行实例

ALTER TABLE some_table ADD COLUMN some_column TEXT NOT NULL DEFAULT '';

无需像bash这样的另一个脚本进行字符串替换。

所以换句话说,有一个简单的方法来获取模式,并在psql中写入一个for循环,它将遍历模式并通过设置search_path来运行每个语句。

原因是租户数量在不断增长,新的租户可以由不是开发人员的管理员用户添加,因此我不断更新我的shell脚本。这只会呈指数级增长。有没有一种处理这类问题的标准方法?

1 个答案:

答案 0 :(得分:3)

你可以用一点PL / pgSQL块来做到这一点:

do
$$
declare
  s_rec record;
begin
  for s_rec in select schema_name 
               from information_schema.schemata
               where schema_name not in ('pg_catalog', 'information_schema')
  loop
     execute format ('ALTER TABLE if exists %I.some_table ADD COLUMN some_column TEXT NOT NULL DEFAULT ''''), s_rec.schema_name);
  end loop;
end;
$$

如果模式中不存在该表,if exists将确保语句不会失败。

如果您过度简化了问题,并且实际上希望为每个模式运行一次完整的脚本,那么为包含实际脚本的每个模式生成脚本可能更容易:

select concat(format('set search_path = %I;', schema_name), 
              chr(10), 
              '\i complete_migration_script.sql')
from information_schema.schemata
where schema_name not in ('pg_catalog', 'information_schema')

您可以将该语句的输出假脱机到一个文件中,然后使用psql运行该文件(当然您需要将complete_migration_script.sql替换为您脚本的实际名称)