【问题标题】:Postgres run statement against multiple schemasPostgres 针对多个模式运行语句
【发布时间】:2017-07-22 08:53:14
【问题描述】:

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

到目前为止,我一直在使用 bash 脚本,其中包含架构列表,每当添加新架构时都需要更新这些架构,并且我需要执行诸如跨帐户更改表架构之类的事情。例如向表中添加新列。

Postgres、psql 等有没有办法运行例如

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

无需在另一个脚本(例如 bash)中进行字符串替换。

换句话说,有没有一种足够简单的方法来获取模式,并在 psql 中编写一个 for 循环,该循环将遍历模式并通过设置 search_path 来运行每个语句。

原因是租户数量在增长,并且新租户可以由非开发人员的管理员用户添加,因此我不断更新我的 shell 脚本。这只会成倍增长。有处理这类问题的标准方法吗?

【问题讨论】:

  • 是的,您可以在主架构 (posgres) 上创建一个过程以获取 INFORMATION_SCHEMA 架构中的所有架构,并对其运行命令进行更改

标签: postgresql


【解决方案1】:

你可以用一个小的 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 替换为您的脚本的实际名称)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 2020-09-17
    相关资源
    最近更新 更多