Implantando mudanças do Esquema do Banco de Dados em um processo de correção [duplicado]

5

Estou enfrentando um problema de metodologia de desenvolvimento conceitual com o qual eu esperava que você pudesse me ajudar. Em primeiro lugar, um pouco de fundo.

Plano de fundo

O projeto que estou desenvolvendo é um aplicativo de nicho que contém um banco de dados de informações, e o público-alvo da minha candidatura são indivíduos particulares no limite inferior da escala de proficiência técnica. Na verdade, essa é a principal razão para o meu projeto: muitas opções semelhantes neste campo existem, mas a grande maioria são aplicativos frágeis e complicados que exigem um alto grau de experiência em programação, banco de dados e sysadmin apenas para continuar em execução. Pior ainda, anos ou mesmo décadas de má manutenção e "melhoria" por programadores amadores que mal entendem o que estavam fazendo, muitas dessas aplicações estão além da capacidade de um profissional não profissional de manter.

O motivo pelo qual comecei este projeto foi dar a eles uma alternativa de baixa barreira de entrada que eles poderiam estender e personalizar razoavelmente via configuração em vez de programação, para centralizar e minimizar a manutenção. Eu mesmo tenho programado por quase 20 anos, mas não até muito recentemente em uma capacidade profissional: Eu sou realmente um engenheiro civil, mas minha principal experiência profissional é ser um representante técnico / cliente para sistemas de gerenciamento de ativos e engenharia de grandes empresas. Então, por favor, desculpe-me se eu não estou 100% atualizado com toda a linguagem profissional ou acadêmica.

Problema

Meu grande problema conceitual é como com segurança e invisibilidade as alterações no banco de dados de mesclagem do usuário final como parte de um processo de atualização. Basicamente, à medida que eu libero versões principais, às vezes extensões para tabelas ou novas tabelas podem ser feitas para o modelo de banco de dados, que precisará ser implementado como parte do processo de correção. No passado, eu só fiz isso em meus próprios servidores de desenvolvimento e minha abordagem foi bastante aleatória e manual.

Como devo proceder para quantificar, preparar e implantar as alterações necessárias no banco de dados como parte do meu aplicativo? Para referência, meu programa é escrito em C # e eu uso o SQL Server (implantado para o usuário que acompanha o aplicativo como o SQL Server Compact Edition). Ainda não selecionei uma plataforma de patches para usar, pois a possível compatibilidade com qualquer metodologia que eu venha a ter aqui pode influenciar minha escolha. Meus pensamentos são de que, quando decido fazer um release, provavelmente existem algumas ferramentas que devo usar para preparar uma diferença de banco de dados entre o último release e o release atual e preparar um script SQL para execução. Então, em algum ponto do processo de instalação, ele deve executar o script SQL e atualizar o banco de dados.

Parece simples, mas não tenho certeza se é possível. A maioria das ferramentas que eu posso encontrar para bancos de dados por aí parece destinada a aplicativos de nível corporativo e administradores de banco de dados, e eu tenho dificuldade em descobrir se eles realmente podem fazer a tarefa simples que eu preciso fazer.

Estou no caminho certo para fazer isso ou há uma abordagem melhor?

    
por Big Luke 29.01.2014 / 03:19
fonte

2 respostas

1

Uma abordagem relativamente simples que usei para um aplicativo SQL CE semelhante é distribuir com a atualização uma lista de instruções SQL que contêm as atualizações cumulativas para o esquema desde a primeira versão do esquema que foi inicialmente distribuído. A instrução SQL final na lista atualizará uma linha em uma tabela de consulta para que o número da versão do esquema seja o mesmo que o release. As instruções SQL podem ser distribuídas como um arquivo ou como um recurso no aplicativo.

UPDATE lookupTable
SET value = 'alarm.wav'
WHERE lookupType = 'sounds' AND lookupId = 'soundFile' AND value = 'test.wav';

ALTER TABLE Users DROP CONSTRAINT UQ__userEmail__00000000000000E0;

UPDATE lookupTable
SET value = '2.8.0.6'
WHERE lookupType = 'version' AND lookupId = 'DataModelVersion';

Em seguida, cada vez que o programa for executado, ele poderá verificar o valor do número da versão do programa em relação ao esquema atual e, se o esquema não for o mesmo, executará o arquivo de esquema mais recente para fazer as alterações no esquema e atualize a versão do esquema, por exemplo

if (!Application.ProductVersion.Equals(schemaVersion)) {
    Schema.UpgradeDatabase(Schema.GetDbConnectionString(), upgradeFile);

O método UpgradeDatabase deve ser capaz de lidar com o fato de que, como a lista de instruções SQL é cumulativa, as instruções insert ou alter anteriores podem encontrar erros de restrição quando forem executadas novamente em um upgrade subseqüente. Isso pode ser resolvido com exceções que não são esperadas, por exemplo,

//SQL Lines are split on ';' and put in a commands array 
foreach (string command in commands) {
    cmd.CommandText = command;
    try {
        cmd.ExecuteNonQuery();
    } catch (Exception exc) {
        // Only throw if it's not an expected error due to rerun of the cumulative statements.
        if (!exc.Message.ToUpper().Contains("VIOLATION OF PRIMARY KEY CONSTRAINT") 
          && !exc.Message.ToUpper().Contains("A DUPLICATE VALUE CANNOT BE INSERTED INTO A UNIQUE INDEX") 
          && !exc.Message.ToUpper().Contains("THE FOREIGN KEY CONSTRAINT DOES NOT EXIST"))
            throw;
    }
}

É claro que o teste deve ser feito em cada versão de patch para garantir que o SQL atualize o banco de dados corretamente e que os erros esperados sejam ignorados. O fato de as instruções SQL serem cumulativas facilita o trabalho de lidar com casos em que um usuário pode ter pulado várias liberações menores antes de instalar uma liberação e a mantém bastante simples.

O método é relativamente simples e trabalhou de forma confiável para atualizar aplicativos clientes que são distribuídos remotamente. A única desvantagem é que ele não lida com uma versão anterior, mas se um patch precisar ser emitido para retornar a algum esquema, isso pode ser feito adicionando mais linhas para alterá-lo de volta para o esquema anterior. / p>     

por 29.01.2014 / 05:09
fonte
1

Escreva scripts SQL com uma quantidade enorme de tratamento de erros neles (procure uma coluna para não existir antes de adicioná-la a uma tabela, procure a tabela para não existir ao criá-la, etc.). Você pode executar os scripts como parte de seu pacote de instalação (os resultados podem variar, pois diferentes instaladores podem facilitar ou dificultar muito mais do que o necessário), ou você pode executar os scripts quando o aplicativo for iniciado. Se você fizer este último, eu recomendaria mover os scripts SQL para outro local para que você não tente executá-los mais de uma vez.

Você pode ver todos os instaladores disponíveis por aí. Eu usei o InnoSetup com bom êxito executando todos os tipos de executáveis depois de colocar meus arquivos nos locais apropriados. Ouvi dizer que é possível fazer o mesmo com um MSI, mas nunca consegui fazê-lo funcionar. Se você decidir usar o WiX, sua ferramenta Gravar pode criar uma instalação executável que fornece tanto um instalador executável quanto um instalador MSI no mesmo pacote.

    
por 29.01.2014 / 05:06
fonte