Estou tentando migrar meus testes de unidade de H2 para Postgresql.
Atualmente, o H2 me fornece um esquema na memória de modo que cada conexão seja mapeada para um esquema exclusivo, crie as tabelas, execute o teste e descarte o esquema. A criação e destruição do esquema são tratadas automaticamente pelo H2.
Os testes de unidade são executados simultaneamente.
Qual é a melhor maneira de fazer isso no Postgresql? Especificamente,
- Como obtenho um esquema exclusivo por conexão?
- A estrutura de teste deve gerar nomes exclusivos ou há um mecanismo integrado para fazer isso?
- Como posso garantir que o esquema seja descartado quando a conexão for interrompida?
- Não quero acabar com esquemas pendentes quando os testes de unidade forem eliminados.
- Qual abordagem produzirá o melhor desempenho?
- Preciso criar/eliminar dezenas de esquemas por segundo.
ATUALIZAÇÃO : Encontrei uma resposta relacionada aqui , mas ela falha ao descartar esquemas caso o processo que executa os testes de unidade seja interrompido.
pg_temp
é um alias para o esquema temporário da sessão atual.Se você fizer um
SET search_path TO pg_temp
antes de executar seus testes, tudo deve funcionar (desde que nada esteja referenciando explicitamente um esquema).Se você não deseja alterar seu script, defina
search_path
o usuário com o qual os testes efetuam login como:Então, tudo o que o usuário criar estará em pg_temp, a menos que seja explicitamente especificado.
Aqui está um exemplo de
psql
, mostrando o esquema real (para esta conexão) para o qual o alias é resolvido:E, como seria de esperar, esse esquema é diferente para cada conexão simultânea e desaparece depois que a conexão é encerrada.
Observe que isso também funciona para funções, embora você tenha que referenciar explicitamente o esquema pg_temp ao chamá-las.
Você pode obter o nome do esquema temporário atual (depois de criar a primeira tabela temporária), conforme apresentado no link que você adicionou:
Mas seu plano atual ainda não faria muito sentido. Para criar tabelas no esquema temporário atual, basta criar tabelas temporárias. Isso é tudo. Por padrão, o
search_path
é definido para que as tabelas temporárias sejam visíveis primeiro. Nunca é necessário qualificar o esquema de tabelas temporárias. Você nunca deveria ter que abordar o esquema temporário atual diretamente de forma alguma - isso é um detalhe de implementação.Seus testes envolvem transações? DDL é transacional no PostgreSQL, portanto, se você criar seu esquema e tabelas e executar seus testes, tudo em uma única transação que é revertida, o esquema nunca é realmente confirmado e visível para outras sessões.
Você ainda precisaria usar um nome provavelmente exclusivo para seu esquema (talvez inclua nome de host e PID), pois
CREATE SCHEMA
falhará imediatamente se já existir um esquema com nome idêntico e será bloqueado se outra sessão tiver criado um esquema com nome idêntico em uma transação não confirmada.Uma alternativa seria apenas usar tabelas temporárias, se você puder modificar seus scripts de criação de banco de dados para fazer isso.
Acabei de ter uma ideia.
O Postgresql garante que uma sessão não possa ver as tabelas temporárias de outra. Acho que isso significa que, quando você cria uma tabela temporária, ela cria um esquema temporário. Então talvez eu possa fazer o seguinte:
Não gosto de confiar em detalhes de implementação, mas neste caso parece bastante seguro.