Estou tentando automatizar a criação de um banco de dados postgres rodando no Windows 10. Gostaria de poder iniciar a partir de uma instalação padrão do postgres e automatizar as seguintes etapas (não necessariamente nesta ordem)
- descartar e recriar um novo banco de dados
- descartar e recriar novos tablespaces
- descartar e recriar novos usuários.
- construir objetos de banco de dados (tabelas, visualizações, procedimentos, gatilhos etc)
- conceder aos usuários as permissões necessárias.
- preencher tabelas com dados iniciais.
Não é muito difícil reduzir isso a uma série de comandos de banco de dados (desde que sejam executados na ordem correta), o problema é que, para alguns comandos, continuo encontrando o erro 'não pode ser emitido dentro de um bloco de transação'. Isso significa que alguns comandos como DROP DATABASE IF EXISTS e CREATE TABLESPACE só podem ser executados (até onde eu sei) dando um passo único manualmente, enquanto eu posso chamar meus scripts de criação de tabela como um único bloco e recriar um 100 tabelas em uma fração de segundo.
Não estou muito preocupado com os poucos segundos extras que estou desperdiçando executando alguns dos comandos individuais, mas, ao fazer alguns deles manualmente, corro o risco de perder etapas e cometer erros.
Como posso automatizar (ou seja, escrever scripts para) todo o processo?
Atualização, o script se parece um pouco com isso ...
DROP DATABASE IF EXISTS ????
DROP TABLESPACE IF EXISTS ????
DROP TABLESPACE IF EXISTS ????
ALTER DEFAULT privileges IN SCHEMA public REVOKE SELECT, INSERT, UPDATE, DELETE ON TABLES FROM ????;
ALTER DEFAULT privileges IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM ????;
DROP USER IF EXISTS ????;
DROP USER IF EXISTS ????;
DROP USER IF EXISTS ????;
CREATE USER ???? PASSWORD '????';
CREATE USER ???? PASSWORD '????';
CREATE USER ???? PASSWORD '????';
CREATE TABLESPACE fastspace OWNER ???? LOCATION 'c:/????/????';
CREATE TABLESPACE slowspace OWNER ???? LOCATION 'd:/????/????';
DROP DATABASE ????;
CREATE DATABASE ????
WITH OWNER = ????
ENCODING = 'UTF8'
TABLESPACE = fastspace
LC_COLLATE = 'English_United Kingdom.1252'
LC_CTYPE = 'English_United Kingdom.1252'
CONNECTION LIMIT = -1;
GRANT CREATE ON DATABASE ???? TO ????;
COMMENT ON DATABASE ????
IS '????database';
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA public TO ????;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO ????;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO ????;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ????;
ALTER DEFAULT privileges IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ????;
Muitos (a maioria) dos comandos acima podem ser executados como parte de um bloco de transação, mas alguns não podem (descartar e criar o banco de dados, por exemplo).
Basta executar o script com o autocommit ativado (o padrão em
psql
) e usar um bloco de transação explícito para aquelas instruções que devem ser executadas em uma única transação: