Estou fazendo um aplicativo da web e preciso fazer uma ramificação para algumas mudanças importantes, o que ocorre é que essas alterações exigem alterações no esquema do banco de dados, então eu gostaria de colocar todo o banco de dados no git também.
Como faço isso? existe uma pasta específica que eu possa manter em um repositório git? Como sei qual? Como posso ter certeza de que estou colocando a pasta correta?
Eu preciso ter certeza, porque essas alterações não são compatíveis com versões anteriores; Não posso me dar ao luxo de estragar.
O banco de dados no meu caso é o PostgreSQL
Editar:
Alguém sugeriu fazer backups e colocar o arquivo de backup sob controle de versão em vez do banco de dados. Para ser sincero, acho isso muito difícil de engolir.
Tem que haver uma maneira melhor.
Atualizar:
OK, então não há uma maneira melhor, mas ainda não estou totalmente convencido, então vou mudar um pouco a questão:
Gostaria de colocar todo o banco de dados sob controle de versão. Qual mecanismo de banco de dados posso usar para que eu possa colocar o banco de dados real sob controle de versão em vez de seu despejo?
O sqlite seria compatível com o git?
Como esse é apenas o ambiente de desenvolvimento, posso escolher o banco de dados que desejar.
Edit2:
O que eu realmente quero não é rastrear meu histórico de desenvolvimento, mas poder mudar do meu ramo "novas mudanças radicais" para o "ramo estável atual" e, por exemplo, corrigir alguns bugs / problemas, etc., com o atual ramo estável. De modo que, quando troco de ramificação, o banco de dados se torna automaticamente magicamente compatível com a ramificação em que estou atualmente. Eu realmente não me importo muito com os dados reais.
bup
Respostas:
Faça um despejo de banco de dados e controle de versão. Dessa forma, é um arquivo de texto simples.
Pessoalmente, sugiro que você mantenha um despejo de dados e um despejo de esquema. Dessa maneira, usando diff, fica bastante fácil ver o que mudou no esquema de revisão em revisão.
Se você estiver fazendo grandes alterações, deverá ter um banco de dados secundário no qual altera o novo esquema e não toque no antigo, pois, como disse que está fazendo uma ramificação.
fonte
Consulte Refatoração de bancos de dados ( http://databaserefactoring.com/ ) para obter um monte de boas técnicas para manter seu banco de dados em conjunto com as alterações de código.
Basta dizer que você está fazendo as perguntas erradas. Em vez de colocar seu banco de dados no git, você deve decompor suas alterações em pequenas etapas verificáveis para poder migrar / reverter as alterações de esquema com facilidade.
Se você deseja ter capacidade de recuperação total, considere arquivar seus logs WAL do postgres e use o PITR (recuperação pontual) para reproduzir / encaminhar transações para estados conhecidos conhecidos específicos.
fonte
Estou começando a pensar em uma solução realmente simples, não sei por que não pensei nisso antes!
Dessa forma, eu posso alternar ramificações sem me preocupar com alterações no esquema do banco de dados.
EDITAR:
Por duplicado, quero dizer criar outro banco de dados com um nome diferente (como
my_db_2
); não fazendo um despejo ou algo assim.fonte
Use algo como LiquiBase para manter o controle de revisão dos seus arquivos Liquibase. você pode marcar alterações somente para produção e manter o banco de dados atualizado para produção ou desenvolvimento (ou qualquer esquema que desejar).
fonte
Enfrentou uma necessidade semelhante e aqui está o que minha pesquisa sobre sistemas de controle de versão de banco de dados levantou:
fonte
ChronicDB
:ChronicDB provides dynamic database upgrades with zero database downtime and inconsistencies.
crunchbase.com/organization/chronicdb#section-overview Um cara chamado Kristis Makris foi um dos fundadores, talvez conhecido pelo SCMBug: mkgnu.net/scmbugExiste um ótimo projeto chamado Migrações no Doctrine, criado apenas para esse fim.
Ainda está no estado alfa e foi construído para php.
http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/index.html
fonte
Eu me deparei com essa pergunta, pois tenho um problema semelhante, onde algo que se aproxima de uma estrutura de diretório baseada em banco de dados, armazena 'arquivos' e preciso do git para gerenciá-lo. É distribuído, através de uma nuvem, usando replicação; portanto, seu ponto de acesso será via MySQL.
A essência das respostas acima, parece sugerir similarmente uma solução alternativa para o problema solicitado, que meio que esquece o ponto, de usar o Git para gerenciar algo em um banco de dados, então tentarei responder a essa pergunta.
Git é um sistema que, em essência, armazena um banco de dados de deltas (diferenças), que podem ser remontados, a fim de reproduzir um contexto. O uso normal do git assume que o contexto é um sistema de arquivos e esses deltas são diferenciais nesse sistema de arquivos, mas na verdade todo o git é um banco de dados hierárquico de deltas (hierárquico, porque na maioria dos casos, cada delta é um commit com pelo menos 1 pais, dispostos em uma árvore).
Desde que você possa gerar um delta, em teoria, o git pode armazená-lo. O problema normalmente é que o git espera que o contexto, no qual está gerando delta, seja um sistema de arquivos e, da mesma forma, quando você faz check-out de um ponto na hierarquia do git, espera gerar um sistema de arquivos.
Se você deseja gerenciar alterações, em um banco de dados, você tem 2 problemas distintos e eu os solucionaria separadamente (se eu fosse você). O primeiro é o esquema, o segundo são os dados (embora na sua pergunta, você declare que os dados não são algo com que se preocupa). Um problema que eu tinha no passado era um banco de dados Dev e Prod, no qual o Dev podia realizar alterações incrementais no esquema, e essas alterações tinham que ser documentadas no CVS e propagadas para viver, além de adições a um dos vários 'estáticos' tabelas. Fizemos isso tendo um terceiro banco de dados, chamado Cruise, que continha apenas os dados estáticos. A qualquer momento, o esquema de Dev e Cruise poderia ser comparado, e tínhamos um script para pegar o diff desses 2 arquivos e produzir um arquivo SQL contendo instruções ALTER, para aplicá-lo. Da mesma forma, quaisquer novos dados, pode ser destilado em um arquivo SQL contendo comandos INSERT. Desde que campos e tabelas sejam adicionados apenas e nunca excluídos, o processo poderá automatizar a geração das instruções SQL para aplicar o delta.
diff
É chamado o mecanismo pelo qual o git gera deltas e o mecanismo pelo qual ele combina 1 ou mais deltas com um arquivomerge
. Se você pode criar um método para diferenciar e mesclar a partir de um contexto diferente, o git deve funcionar, mas como foi discutido, você pode preferir uma ferramenta que faça isso por você. Meu primeiro pensamento para resolver isso é este https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools que detalha como substituir o diff interno do git e ferramenta de mesclagem. Atualizarei esta resposta, à medida que encontrar uma solução melhor para o problema, mas, no meu caso, espero ter que gerenciar apenas alterações de dados, até o ponto em que um armazenamento de arquivos baseado em banco de dados possa mudar, portanto, minha solução pode não ser exatamente o que você precisa.fonte
Dê uma olhada no RedGate SQL Source Control.
http://www.red-gate.com/products/sql-development/sql-source-control/
Essa ferramenta é um snap-in do SQL Server Management Studio que permitirá que você coloque seu banco de dados no Source Control with Git.
É um pouco caro por US $ 495 por usuário, mas há uma avaliação gratuita de 28 dias disponível.
NOTA Eu não sou afiliado à RedGate de nenhuma maneira.
fonte
Quero fazer algo semelhante, adicionar minhas alterações no banco de dados ao meu sistema de controle de versão.
Vou seguir as idéias deste post de Vladimir Khorikov "Melhores práticas de controle de versão de banco de dados" . Em resumo, vou
Caso isso ajude!
fonte
Eu tenho procurado o mesmo recurso para o Postgres (ou bancos de dados SQL em geral) há algum tempo, mas não achei ferramentas adequadas (simples e intuitivas) o suficiente. Provavelmente, isso se deve à natureza binária de como os dados são armazenados. Klonio parece ideal, mas parece morto. Noms DB parece interessante (
e vivo). Veja também o Irmin (baseado em OCaml com propriedades Git).Embora isso não responda à pergunta, pois funcionaria com o Postgres, consulte o banco de dados Flur.ee. Possui um recurso de "viagem no tempo" que permite consultar os dados de um ponto no tempo arbitrário. Estou supondo que deve ser capaz de trabalhar com um modelo de "ramificação".
Esse banco de dados foi desenvolvido recentemente para fins de blockchain. Devido à natureza das blockchains, os dados precisam ser registrados em incrementos, que é exatamente como o git funciona. Eles estão visando um lançamento de código aberto no segundo trimestre de 2019 .
Atualização : Confira também o banco de dados Crux , que pode consultar a dimensão temporal das inserções, que você pode ver como 'versões'. O ponto crucial parece ser uma implementação de código aberto do altamente apreciado Datomic.
fonte
Você não pode fazê-lo sem atomicidade e não pode obter atomicidade sem usar pg_dump ou um sistema de arquivos de captura instantânea.
Minha instância do postgres está no zfs, que eu tiro instantaneamente. É aproximadamente instantâneo e consistente.
fonte
O que você deseja, em espírito, talvez seja algo como o Post Facto , que armazena versões de um banco de dados em um banco de dados. Confira esta apresentação .
Aparentemente, o projeto nunca foi realmente a lugar algum, então provavelmente não o ajudará imediatamente, mas é um conceito interessante. Receio que fazer isso corretamente seja muito difícil, porque até a versão 1 precisaria acertar todos os detalhes para que as pessoas confiassem seu trabalho.
fonte
Lancei uma ferramenta para sqlite que faz o que você está pedindo. Ele usa um driver diff personalizado que utiliza a ferramenta de projetos do sqlite 'sqldiff', os UUIDs como chaves primárias e deixa de fora o sqlite rowid. Ainda está em alfa, então o feedback é apreciado.
O Postgres e o mysql são mais complicados, pois os dados binários são mantidos em vários arquivos e podem até não ser válidos se você puder capturá-los.
https://github.com/cannadayr/git-sqlite
fonte
Eu acho que o X-Istence está no caminho certo, mas há mais algumas melhorias que você pode fazer nessa estratégia. Primeiro uso:
despejar as tabelas, seqüências, etc. e colocar esse arquivo sob controle de versão. Você usará isso para separar as alterações de compatibilidade entre suas filiais.
Em seguida, execute um despejo de dados para o conjunto de tabelas que contêm a configuração necessária para que seu aplicativo funcione (provavelmente deve ignorar dados do usuário, etc.), como padrões de formulário e outros dados não modificáveis por usuário. Você pode fazer isso seletivamente usando:
Essa é uma boa idéia, pois o repositório pode ficar muito complicado quando o banco de dados atinge 100 Mb + ao fazer um despejo de dados completo. Uma idéia melhor é fazer backup de um conjunto de dados mais mínimo necessário para testar seu aplicativo. Se os dados padrão forem muito grandes, isso ainda poderá causar problemas.
Se você absolutamente precisar colocar backups completos no repositório, considere fazê-lo em uma ramificação fora da sua árvore de origem. Um sistema de backup externo com alguma referência à svn rev correspondente provavelmente é melhor para isso.
Além disso, sugiro usar dumps de formato de texto sobre binários para fins de revisão (pelo menos para o esquema), pois são mais fáceis de diferenciar. Você sempre pode compactá-las para economizar espaço antes do check-in.
Por fim, dê uma olhada na documentação de backup do postgres, se você ainda não o fez. A maneira como você está comentando sobre o backup do 'banco de dados' em vez de um despejo me faz pensar se você está pensando em backups baseados em sistema de arquivos (consulte a seção 23.2 para advertências).
fonte
Esta pergunta é praticamente respondida, mas eu gostaria de complementar a resposta de X-Istence e Dana the Sane com uma pequena sugestão.
Se você precisar de controle de revisão com algum grau de granularidade, digamos diariamente, poderá associar o despejo de texto das tabelas e do esquema a uma ferramenta como rdiff-backup, que faz backups incrementais. A vantagem é que, em vez de armazenar instantâneos de backups diários, você simplesmente armazena as diferenças do dia anterior.
Com isso, você tem a vantagem do controle de revisão e não perde muito espaço.
De qualquer forma, usar o git diretamente em grandes arquivos simples que mudam com muita frequência não é uma boa solução. Se seu banco de dados ficar muito grande, o git começará a ter alguns problemas no gerenciamento dos arquivos.
fonte
Aqui está o que estou tentando fazer em meus projetos:
A configuração do banco de dados é armazenada no arquivo de configuração que não está sob controle de versão (.gitignore)
Os padrões do banco de dados (para configurar novos projetos) são um arquivo SQL simples sob controle de versão.
Para o esquema do banco de dados, crie um dump do esquema do banco de dados sob o controle de versão.
A maneira mais comum é ter scripts de atualização que contenham instruções SQL (ALTER Table .. ou UPDATE). Você também precisa ter um lugar em seu banco de dados onde salve a versão atual do seu esquema)
Dê uma olhada em outros grandes projetos de banco de dados de código aberto (piwik ou seu sistema cms favorito), todos eles usam scripts de atualização (1.sql, 2.sql, 3.sh, 4.php.5.sql)
Mas esse é um trabalho muito demorado, você precisa criar e testar os scripts de atualização e precisa executar um script de atualização comum que compare a versão e execute todos os scripts de atualização necessários.
Então, teoricamente (e é isso que estou procurando), você pode despejar o esquema do banco de dados após cada alteração (manualmente, conjob, git hooks (talvez antes do commit)) (e apenas em alguns casos muito especiais criar updatescripts)
Depois disso, no seu script de atualização comum (execute os scripts de atualização normais, para os casos especiais), compare os esquemas (o dump e o banco de dados atual) e gere automaticamente as Instruções ALTER. Existem algumas ferramentas que já podem fazer isso, mas ainda não foram boas.
fonte
Eu recomendaria o neXtep para controlar a versão do banco de dados. Ele possui um bom conjunto de documentação e fóruns que explica como instalar e os erros encontrados. Eu testei para o postgreSQL 9.1 e 9.3, consegui fazê-lo funcionar para a 9.1, mas para a 9.3 parece não funcionar.
fonte
O que faço em meus projetos pessoais é que eu armazeno meu banco de dados inteiro no dropbox e aponto o fluxo de trabalho do MAMP, WAMP para usá-lo a partir daí. Dessa forma, o banco de dados está sempre atualizado, sempre que eu precisar fazer algum desenvolvimento. Mas isso é apenas para dev! Sites ao vivo está usando servidor próprio para isso fora do curso! :)
fonte
Armazenar cada nível de alterações no banco de dados sob o controle de versão git é como empurrar todo o banco de dados com cada confirmação e restaurar todo o banco de dados com cada solicitação. Se o seu banco de dados é tão propenso a mudanças cruciais e você não pode dar ao luxo de perdê-los, você pode simplesmente atualizar seu pre_commit e post_merge ganchos. Fiz o mesmo com um dos meus projetos e você pode encontrar as instruções aqui .
fonte
É assim que eu faço:
Como você tem uma escolha livre sobre o tipo de banco de dados, use um banco de dados baseado em arquivo como, por exemplo, firebird.
Crie um banco de dados modelo que tenha o esquema que se adapta à sua ramificação real e armazene-a no seu repositório.
Ao executar seu aplicativo, programaticamente, crie uma cópia do seu banco de dados modelo, armazene-o em outro lugar e trabalhe com essa cópia.
Dessa forma, você pode colocar seu esquema de banco de dados sob controle de versão sem os dados. E se você alterar seu esquema, basta alterar o DB do modelo
fonte
Costumávamos executar um site social, em uma configuração padrão do LAMP. Tínhamos um servidor ao vivo, um servidor de teste e um servidor de desenvolvimento, além de máquinas de desenvolvedores locais. Todos foram gerenciados usando o GIT.
Em cada máquina, tínhamos os arquivos PHP, mas também o serviço MySQL, e uma pasta com imagens que os usuários carregavam. O servidor Live cresceu para ter cerca de 100K (!) Usuários recorrentes, o despejo era de cerca de 2GB (!), A pasta Image era de cerca de 50GB (!). Quando saí, nosso servidor estava atingindo o limite de sua CPU, Ram e, acima de tudo, os limites de conexão de rede simultâneos (até compilamos nossa própria versão do driver da placa de rede para maximizar o servidor 'lol'). Não foi possível ( nem você deve assumir com seu site ) colocar 2 GB de dados e 50 GB de imagens no GIT.
Para gerenciar tudo isso no GIT com facilidade, ignoraríamos as pastas binárias (as pastas que contêm as imagens) inserindo esses caminhos de pasta no .gitignore. Também tínhamos uma pasta chamada SQL fora do caminho da raiz do documento Apache. Nessa pasta SQL, colocaríamos nossos arquivos SQL dos desenvolvedores em numerações incrementais (001.florianm.sql, 001.johns.sql, 002.florianm.sql, etc). Esses arquivos SQL também foram gerenciados pelo GIT. O primeiro arquivo sql realmente conteria um grande conjunto de esquemas de banco de dados. Não adicionamos dados do usuário no GIT (por exemplo, os registros da tabela de usuários ou da tabela de comentários), mas dados como configurações, topologia ou outros dados específicos do site foram mantidos nos arquivos sql (e, portanto, pelo GIT). Principalmente, são os desenvolvedores (que conhecem melhor o código) que determinam o que e o que não é mantido pelo GIT com relação ao esquema e aos dados SQL.
Quando chegou a uma versão, o administrador efetua login no servidor dev, mescla a ramificação ativa com todos os desenvolvedores e ramificações necessárias na máquina dev em uma ramificação de atualização e a envia ao servidor de teste. No servidor de teste, ele verifica se o processo de atualização do servidor Live ainda é válido e, em rápida sucessão, aponta todo o tráfego no Apache para um site de espaço reservado, cria um dump de banco de dados, aponta o diretório de trabalho da atualização 'ao vivo' para ' ', executa todos os novos arquivos sql no mysql e redireciona o tráfego para o site correto. Quando todas as partes interessadas concordaram após revisar o servidor de teste, o Administrador fez o mesmo do servidor de Teste ao servidor Live. Posteriormente, ele mescla a ramificação ativa no servidor de produção, para a ramificação mestre em todos os servidores, e refaz o rebase de todas as ramificações ativas.
Se houve problemas no servidor de teste, por exemplo. as mesclagens tiveram muitos conflitos, o código foi revertido (apontando o ramo de trabalho de volta para 'live') e os arquivos sql nunca foram executados. No momento em que os arquivos sql foram executados, isso foi considerado uma ação não reversível na época. Se os arquivos SQL não estavam funcionando corretamente, o banco de dados foi restaurado usando o Dump (e os desenvolvedores informaram, por fornecer arquivos SQL mal testados).
Hoje, mantemos uma pasta sql-up e sql-down, com nomes de arquivos equivalentes, onde os desenvolvedores precisam testar se os arquivos sql de atualização podem ser igualmente rebaixados. Em última análise, isso poderia ser executado com um script bash, mas é uma boa idéia se os olhos humanos continuem monitorando o processo de atualização.
Não é ótimo, mas é administrável. Espero que isso dê uma ideia de um site prático, prático e com relativamente alta disponibilidade. Seja um pouco desatualizado, mas ainda seguido.
fonte
Use uma ferramenta como o iBatis Migrations ( manual , pequeno tutorial em vídeo ) que permite controlar a versão das alterações feitas em um banco de dados durante todo o ciclo de vida de um projeto, em vez do próprio banco de dados.
Isso permite aplicar seletivamente alterações individuais a diferentes ambientes, manter um registro de alterações em quais ambientes, criar scripts para aplicar as alterações de A a N, alterações de reversão etc.
fonte
Isso não depende do mecanismo do banco de dados. Pelo Microsoft SQL Server, existem muitos programas de controle de versão. Eu não acho que esse problema possa ser resolvido com o git, você precisa usar um sistema de controle de versão de esquema específico do pgsql. Não sei se existe ou não ...
fonte
Atualização 26 de agosto de 2019:
O Netlify CMS está fazendo isso com o GitHub, um exemplo de implementação pode ser encontrado aqui com todas as informações sobre como eles o implementaram netlify-cms-backend-github
fonte