Tenho vários bancos de dados na mesma instância e estou atualizando um esquema de tabela que deve se propagar por todos os bancos de dados.
Não tenho certeza se sei qual é o procedimento certo para isso, mas acho que deveria ser mais ou menos assim?
DO $$DECLARE r record;
BEGIN
FOR r IN SELECT datname FROM pg_database WHERE datistemplate = false
LOOP
EXECUTE 'ALTER TABLE public.' || quote_ident(r) || ' ALTER VARCHAR(200);';
EXECUTE ...
END LOOP;
END;
$$;
Alguma ideia?
Acho que a pergunta fundamental que você precisa se fazer é quanta garantia você precisa de que isso se propagou para todos os bancos de dados. Você precisa de todas as alterações para confirmar ou reverter juntas? Nesse caso, você provavelmente deve escrever um script em uma linguagem de programação de sua escolha (Perl, Python ou semelhante), enviar o bloco DO para lá e usar PREPARE TRANSACTION em cada conexão db (você abriria uma conexão por db ). Se tudo isso for bem-sucedido, você se compromete. Se qualquer um falhar, você reverte.
Na verdade, esta é uma aplicação muito útil do ddl transacional do PostgreSQL, pois você pode garantir que todos os seus bancos de dados tenham esquemas mantidos em sincronia.
Em primeiro lugar, se você estivesse usando o tipo de dados
text
orvarchar
(sem o modificador de comprimento) em vez do praticamente inútilvarchar(n)
, você não estaria nessa situação difícil para começar. Se você realmente precisa impor um comprimento máximo, useCHECK
restrições para isso, elas podem ser alteradas sem mexer na estrutura da tabela.Mais detalhes nesta resposta relacionada no SO.
Em seguida, você não pode executar o comando SQL em nenhum outro banco de dados além daquele ao qual está conectado no PostgreSQL padrão neste momento. Isso inclui bancos de dados no mesmo cluster. Se você tentar, receberá um erro como:
Para executar comandos SQL em outros bancos de dados (Postgres), você pode instalar o módulo adicional dblink . Cito o manual aqui :
Em seguida, você pode refinar sua
DO
declaração comdblink
chamadas.No Linux, você pode usar este simples trecho de shell: