O objetivo do artigo é usar a biblioteca de guardiões de esquema como um exemplo para mostrar ferramentas para simplificar o desenvolvimento de bancos de dados em projetos PHP usando DBMSs do PostgreSQL.
Os seguintes problemas serão abordados:
- De que forma armazenar um despejo da estrutura do banco de dados no sistema de controle de versão (daqui em diante - VCS)
- Como rastrear alterações na estrutura do banco de dados após salvar o dump
- Como transferir alterações na estrutura do banco de dados para outros ambientes sem conflitos e arquivos de migração gigantes
- Como estabelecer um processo de trabalho paralelo em um projeto por vários desenvolvedores
- Como implantar com segurança mais alterações na estrutura do banco de dados no ambiente de produção
As informações deste artigo serão úteis principalmente para desenvolvedores que desejam aproveitar ao máximo os recursos do PostgreSQL, mas enfrentam problemas para manter a lógica de negócios no banco de dados.
O artigo não descreverá as vantagens ou desvantagens de armazenar a lógica de negócios em um banco de dados. Supõe-se que a escolha já tenha sido feita pelo leitor.
O SchemaKeeper foi desenvolvido para trabalhar com procedimentos armazenados escritos em PL / pgSQL . O teste com outros idiomas não foi realizado, portanto, o uso pode não ser tão eficaz ou impossível.
De que forma armazenar um despejo da estrutura do banco de dados no VCS
A biblioteca do guardião de esquema fornece a função saveDump , que salva a estrutura dos objetos do banco de dados como arquivos de texto separados. A saída cria um diretório que contém a estrutura do banco de dados, dividida em arquivos agrupados que são fáceis de adicionar ao VCS.
Considere converter objetos de um banco de dados em arquivos com alguns exemplos:
O conteúdo do arquivo é uma representação textual da estrutura de um objeto de banco de dados específico. Por exemplo, para procedimentos armazenados, o conteúdo do arquivo será a definição completa do procedimento armazenado, começando com o bloco CREATE OR REPLACE FUNCTION
.
Como pode ser visto na tabela acima, o caminho do arquivo armazena informações sobre o tipo, esquema e nome do objeto. Essa abordagem facilita a navegação pelas alterações de despejo e revisão de código no banco de dados.
A .sql
para arquivos com código-fonte para procedimentos armazenados é selecionada para que o IDE forneça automaticamente ferramentas para interagir com o banco de dados ao abrir o arquivo.
Como rastrear alterações na estrutura do banco de dados após salvar o dump
Depois de salvar um despejo da estrutura atual do banco de dados no VCS, temos a oportunidade de verificar se foram feitas alterações na estrutura do banco de dados após a criação do despejo. A biblioteca do detentor de esquema fornece uma função CheckerDump para detectar alterações na estrutura do banco de dados, que retorna informações sobre diferenças sem efeitos colaterais.
Uma maneira alternativa de verificar é chamar a função saveDump
, especificando o mesmo diretório e verificar alterações no VCS. Como os objetos do banco de dados são armazenados em arquivos separados, o VCS mostrará apenas objetos alterados. A principal desvantagem desse método é a necessidade de substituir arquivos para ver as alterações.
Como transferir alterações na estrutura do banco de dados para outros ambientes sem conflitos e arquivos de migração gigantes
Graças à função deployDump, o código fonte dos procedimentos armazenados é editado como o restante do código fonte do aplicativo. A modificação do procedimento armazenado ocorre fazendo alterações no arquivo correspondente, o que é refletido automaticamente no sistema de controle de versão.
Por exemplo, para criar um novo procedimento armazenado no esquema public
, basta criar um novo arquivo com a extensão .sql
no diretório public/functions
, colocar nele o código fonte do procedimento armazenado, incluindo o bloco CREATE OR REPLACE FUNCTION
, e chamar a função deployDump
. Da mesma forma, um procedimento armazenado é modificado e excluído. Assim, o código entra simultaneamente no VCS e no banco de dados.
Se um erro aparecer no código-fonte do procedimento armazenado, o deployDump
falhará, lançando uma exceção. A incompatibilidade de procedimentos armazenados entre o dump e o banco de dados atual não é possível usando deployDump
.
Ao criar um novo procedimento armazenado, não há necessidade de inserir manualmente o nome do arquivo correto. É suficiente que o arquivo tenha a extensão .sql
. O nome correto pode ser obtido no valor de retorno da função deployDump
e usado para renomear o arquivo.
deployDump
altera os parâmetros da função ou do tipo de retorno sem ações adicionais, enquanto na abordagem clássica seria necessário executar a DROP FUNCTION
e somente então CREATE OR REPLACE FUNCTION
.
Infelizmente, em algumas situações, deployDump
falha ao aplicar automaticamente as alterações. Por exemplo, se uma função de gatilho usada por pelo menos um gatilho for excluída. Tais situações são resolvidas manualmente usando arquivos de migração.
Se o responsável pelo esquema for responsável pela transferência de alterações nos procedimentos armazenados, os arquivos de migração serão usados para transferir outras alterações na estrutura. Por exemplo, a biblioteca de doutrinas / migrações é adequada.
As migrações devem ser aplicadas antes da execução do deployDump
para fazer alterações na estrutura e resolver possíveis situações problemáticas.
O trabalho com migrações será descrito em mais detalhes nas seções a seguir.
Como estabelecer um processo de trabalho paralelo em um projeto por vários desenvolvedores
Vamos criar um script para a inicialização completa do banco de dados, que os desenvolvedores executam em máquinas locais para alinhar a estrutura dos bancos de dados locais com o dump armazenado no VCS. Dividimos a inicialização do banco de dados local em 3 etapas:
- Importe um arquivo com uma estrutura básica, que será chamada, por exemplo,
base.sql
- Aplicação de migrações
- Chamada
deployDump
base.sql
é o ponto de partida sobre o qual as migrações são aplicadas e o deployDump
é deployDump
, ou seja, base.sql + + deployDump =
. Utilizado pelo base.sql
exclusivamente ao inicializar o banco de dados do zero. Esse arquivo é gerado usando pg_dump .
Chamamos o script para a inicialização completa do banco de dados refresh.sh
. O fluxo de trabalho do desenvolvedor é o seguinte:
- Executando
refresh.sh
em seu ambiente para obter a estrutura atual do banco de dados - O início do trabalho na tarefa, a modificação do banco de dados local de acordo com as necessidades da nova funcionalidade (
ALTER TABLE ... ADD COLUMN
, etc.) - Após concluir a tarefa, chame a função
saveDump
para confirmar as alterações feitas no banco de dados no VCS refresh.sh
verifyDump
e verifyDump
para exibir uma lista de alterações a serem incluídas na migração- A transferência de alterações de estrutura no arquivo de migração, executando
verifyDump
e verifyDump
, e se a migração estiver verifyDump
corretamente, verifyDump
mostrará que não há diferenças entre o banco de dados local e o dump salvo.
O processo descrito acima é compatível com os princípios do gitflow
. Cada filial no VCS contém sua própria versão do despejo e, quando as ramificações se fundem, os despejos se fundem. As fusões são executadas sem ações adicionais, mas se forem feitas alterações nas ramificações, por exemplo, na mesma tabela, é possível um conflito.
Considere uma situação de conflito usando o exemplo de uma ramificação de desenvolvimento , da qual ramificação1 e ramificação2 são ramificadas , que não conflitam com o desenvolvimento , mas conflitam entre si. A tarefa é mesclar branch1 e branch2 no desenvolvimento. Nesse caso, é recomendável mesclar branch1 no desenvolvimento e depois mesclar o desenvolvimento no branch2 , resolvendo conflitos no branch2 e, em seguida, mesclar o branch2 no desenvolvimento. No estágio da resolução de conflitos, talvez seja necessário corrigir o arquivo de migração no branch2 para que ele corresponda ao dump final, que inclui os resultados das fusões.
Como implantar com segurança mais alterações na estrutura do banco de dados no ambiente de produção
A presença no despejo VCS da estrutura atual do banco de dados permite verificar a base de produção quanto à conformidade exata com a estrutura necessária. Isso garante que todas as alterações pretendidas pelos desenvolvedores foram transferidas para a base de produção.
Como o DDL no PostgreSQL é transacional , é recomendável seguir a ordem de implantação para que, no caso de um erro inesperado, o ROLLBACK
"indolor":
- Iniciar transação
- Executar todas as migrações em uma transação
- Na mesma transação, execute
deployDump
- Sem concluir a transação, execute
verifyDump
. Se não houver erros, execute COMMIT
. Se houver erros, execute ROLLBACK
Essas etapas são bastante fáceis de integrar às abordagens existentes para implantar aplicativos, incluindo tempo de inatividade zero.
Conclusão
Graças aos métodos descritos acima, você pode reduzir o desempenho máximo dos projetos "PHP + PostgreSQL", sacrificando uma quantidade relativamente pequena de conveniência de desenvolvimento em comparação com a implementação de toda lógica de negócios no código principal do aplicativo. Além disso, o processamento de dados no PL / pgSQL geralmente parece mais transparente e requer menos código do que a mesma funcionalidade escrita em PHP.