Tive dificuldade para encontrar bons exemplos de como gerenciar esquemas e dados de banco de dados entre servidores de desenvolvimento, teste e produção.
Aqui está a nossa configuração. Cada desenvolvedor tem uma máquina virtual executando nosso aplicativo e o banco de dados MySQL. É sua caixa de areia pessoal fazer o que quiserem. Atualmente, os desenvolvedores fazem uma alteração no esquema SQL e fazem um despejo do banco de dados em um arquivo de texto que eles confirmam no SVN.
Queremos implantar um servidor de desenvolvimento de integração contínua que sempre esteja executando o código confirmado mais recente. Se fizermos isso agora, ele recarregará o banco de dados do SVN para cada build.
Temos um servidor de teste (virtual) que executa "liberar candidatos". A implantação no servidor de teste atualmente é um processo muito manual e geralmente envolve o carregamento do SQL mais recente do SVN e o aprimoramento. Além disso, os dados no servidor de teste são inconsistentes. Você acaba com quaisquer dados de teste que o último desenvolvedor confirmar no seu servidor sandbox.
Onde tudo quebra é a implantação na produção. Como não podemos sobrescrever os dados ativos com dados de teste, isso envolve recriar manualmente todas as alterações de esquema. Se houver um grande número de alterações de esquema ou scripts de conversão para manipular os dados, isso pode ficar muito complicado.
Se o problema fosse apenas o esquema, seria um problema mais fácil, mas também existem dados "básicos" no banco de dados que são atualizados durante o desenvolvimento, como metadados nas tabelas de segurança e permissões.
Essa é a maior barreira que vejo ao avançar para a integração contínua e a criação de uma etapa. Como você resolve isso?
Uma pergunta de acompanhamento: como você controla as versões do banco de dados para saber quais scripts executar para atualizar uma determinada instância de banco de dados? Uma tabela de versões como Lance menciona abaixo do procedimento padrão?
Obrigado pela referência a Tarantino. Não estou em um ambiente .NET, mas achei a página wiki do DataBaseChangeMangement muito útil. Especialmente esta apresentação em Powerpoint (.ppt)
Vou escrever um script Python que verifica os nomes dos *.sql
scripts em um determinado diretório em uma tabela no banco de dados e executa os que não estão lá em ordem, com base em um número inteiro que forma a primeira parte do nome do arquivo. Se for uma solução bastante simples, como suspeito, será postada aqui.
Eu tenho um script de trabalho para isso. Ele lida com a inicialização do banco de dados, se ele não existir, e com a execução de scripts de atualização, conforme necessário. Também existem opções para limpar um banco de dados existente e importar dados de teste de um arquivo. São cerca de 200 linhas, por isso não vou publicá-lo (embora eu possa colocá-lo no pastebin, se houver interesse).
Respostas:
Existem algumas boas opções. Eu não usaria a estratégia "restaurar um backup".
Faça o script de todas as alterações no esquema e faça com que o servidor de IC execute esses scripts no banco de dados. Tenha uma tabela de versões para acompanhar a versão atual do banco de dados e execute os scripts apenas se forem de uma versão mais recente.
Use uma solução de migração. Essas soluções variam de acordo com o idioma, mas, para o .NET, eu uso o Migrator.NET. Isso permite que você versão seu banco de dados e mover para cima e para baixo entre versões. Seu esquema é especificado no código C #.
fonte
Seus desenvolvedores precisam escrever scripts de alteração (esquema e alteração de dados) para cada bug / recurso em que trabalham, não apenas despejar todo o banco de dados no controle de origem. Esses scripts atualizarão o banco de dados de produção atual para a nova versão em desenvolvimento.
Seu processo de construção pode restaurar uma cópia do banco de dados de produção em um ambiente apropriado e executar todos os scripts do controle de origem, o que atualizará o banco de dados para a versão atual. Fazemos isso diariamente para garantir que todos os scripts sejam executados corretamente.
fonte
Veja como o Ruby on Rails faz isso.
Primeiro, existem os chamados arquivos de migração, que basicamente transformam o esquema e os dados do banco de dados da versão N para a versão N + 1 (ou, no caso de fazer o downgrade da versão N + 1 para N). O banco de dados possui uma tabela que informa a versão atual.
Os bancos de dados de teste são sempre limpos antes dos testes de unidade e preenchidos com dados fixos de arquivos.
fonte
O livro Refatorando Bancos de Dados: Design Evolucionário de Banco de Dados pode fornecer algumas idéias sobre como gerenciar o banco de dados. Uma versão curta também pode ser lida em http://martinfowler.com/articles/evodb.html
Em um projeto PHP + MySQL, eu tinha o número da revisão do banco de dados armazenado no banco de dados e, quando o programa se conecta ao banco de dados, ele primeiro verifica a revisão. Se o programa exigir uma revisão diferente, ele abrirá uma página para atualizar o banco de dados. Cada atualização é especificada no código PHP, que altera o esquema do banco de dados e migra todos os dados existentes.
fonte
dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>
(Obviamente, você nunca deve codificar nomes de banco de dadosfonte
Isso é algo com o qual estou constantemente insatisfeito - nossa solução para esse problema. Por vários anos, mantivemos um script de alteração separado para cada versão. Este script conteria os deltas da última versão de produção. A cada versão do aplicativo, o número da versão aumentava, fornecendo algo como o seguinte:
Isso funcionou bem o suficiente até que começamos a manter duas linhas de desenvolvimento: Trunk / Mainline para novo desenvolvimento e uma ramificação de manutenção para correções de bugs, aprimoramentos de curto prazo etc. Inevitavelmente, surgiu a necessidade de fazer alterações no esquema na ramificação. Nesse ponto, já tínhamos dbChanges_n + 1.sql no tronco, então acabamos seguindo um esquema como o seguinte:
Novamente, isso funcionou bem o suficiente, até que um dia procuramos e vimos 42 scripts delta na linha principal e 10 na filial. ARGH!
Hoje em dia, simplesmente mantemos um script delta e deixamos o SVN versão - ou seja, substituímos o script a cada versão. E evitamos fazer alterações de esquema nas ramificações.
Então, eu também não estou satisfeito com isso. Eu realmente gosto do conceito de migrações do Rails. Fiquei bastante fascinado com o LiquiBase . Ele suporta o conceito de refatoração incremental de banco de dados. Vale a pena dar uma olhada e em breve vou ver isso em detalhes. Alguém tem experiência com isso? Eu ficaria muito curioso em saber sobre seus resultados.
fonte
Você também pode usar uma ferramenta como o SQL Compare para escrever a diferença entre várias versões de um banco de dados, permitindo migrar rapidamente entre versões
fonte
Temos uma configuração muito semelhante ao OP.
Os desenvolvedores desenvolvem em VMs com bancos de dados privados.
[Em breve, os desenvolvedores se comprometerão em filiais privadas]
O teste é executado em máquinas diferentes (na verdade, nas VMs hospedadas em um servidor) [em breve será executado pelo servidor Hudson CI]
Teste carregando o dump de referência no db. Aplique os patches de esquema dos desenvolvedores e aplique os patches de dados dos desenvolvedores
Em seguida, execute os testes de unidade e sistema.
A produção é implantada nos clientes como instaladores.
O que nós fazemos:
Tomamos um despejo de esquema do nosso banco de dados de sandbox. Em seguida, um dump de dados sql. Diferenciamos isso da linha de base anterior. esse par de deltas é atualizar n-1 para n.
nós configuramos os dumps e deltas.
Portanto, para instalar a versão N CLEAN, executamos o dump em um db vazio. Para aplicar patches, aplique os patches intermediários.
(Juha mencionou a ideia de Rail de ter uma tabela gravando a versão atual do banco de dados é boa e deve tornar a instalação das atualizações menos complicada.)
Deltas e lixões devem ser revistos antes do teste beta. Não vejo como contornar isso, pois vi desenvolvedores inserirem contas de teste no banco de dados por conta própria.
fonte
Receio estar de acordo com outros pôsteres. Os desenvolvedores precisam criar um script de suas alterações.
Em muitos casos, um ALTER TABLE simples não funciona, você também precisa modificar os dados existentes - os desenvolvedores precisam pensar sobre quais migrações são necessárias e garantir que estejam com o script correto (é claro que você deve testá-las com cuidado em algum momento) o ciclo de lançamento).
Além disso, se você tiver algum sentido, você também fará com que seus desenvolvedores criem reversões de scripts para as alterações, para que possam ser revertidos, se necessário. Isso também deve ser testado, para garantir que sua reversão não seja executada apenas sem erros, mas deixe o banco de dados no mesmo estado em que estava anteriormente (isso nem sempre é possível ou desejável, mas é uma boa regra na maioria das vezes) .
Como você conecta isso a um servidor de IC, eu não sei. Talvez o servidor de IC precise ter um instantâneo de construção conhecido, o qual reverte a cada noite e depois aplica todas as alterações desde então. Provavelmente, isso é melhor, caso contrário, um script de migração quebrado não quebrará apenas a compilação daquela noite, mas todas as subseqüentes.
fonte
Confira o dbdeploy , já existem ferramentas Java e .net disponíveis, você pode seguir os padrões para layouts de arquivos SQL e tabela de versões de esquema e escrever sua versão python.
fonte
Estamos usando a linha de comando mysql-diff : gera uma diferença entre dois esquemas de banco de dados (do banco de dados ou script ativo) como script ALTER. O mysql-diff é executado no início do aplicativo e, se o esquema for alterado, ele será reportado ao desenvolvedor. Portanto, os desenvolvedores não precisam escrever ALTERs manualmente, as atualizações de esquema acontecem semiautomáticas.
fonte
Se você estiver no ambiente .NET, a solução será Tarantino (arquivada) . Ele lida com tudo isso (incluindo quais scripts sql instalar) em uma compilação NANT.
fonte
Eu escrevi uma ferramenta que (conectando-se ao Open DBDiff ) compara esquemas de banco de dados e sugere scripts de migração para você. Se você fizer uma alteração que exclua ou modifique os dados, ocorrerá um erro, mas fornecerá uma sugestão para o script (por exemplo, quando uma coluna estiver ausente no novo esquema, ele verificará se a coluna foi renomeada e criará xx - gerado script.sql.suggestion contendo uma declaração de renomeação).
http://code.google.com/p/migrationscriptgenerator/ Apenas para SQL Server Receio :( Também é bastante alfa, mas é muito baixo atrito (principalmente se você combiná-lo com Tarantino ou http://code.google .com / p / simplescriptrunner / )
O jeito que eu uso é ter um projeto de scripts SQL no seu .sln. Você também tem um banco de dados db_next localmente no qual faz alterações (usando o Management Studio ou o NHibernate Schema Export ou o LinqToSql CreateDatabase ou algo assim). Em seguida, você executa o migrationscriptgenerator com os bancos de dados _dev e _next, que são criados. os scripts de atualização SQL para a migração.
fonte
Para o banco de dados oracle, usamos as ferramentas oracle-ddl2svn .
Essa ferramenta automatizou o próximo processo
mudanças entre instâncias resolvidas manualmente
fonte