Devo adicionar os arquivos de migração do Django no arquivo .gitignore?

130

Devo adicionar os arquivos de migração do Django no .gitignorearquivo?

Recentemente, tenho recebido muitos problemas de git devido a conflitos de migração e queria saber se deveria marcar os arquivos de migração como ignorar.

Em caso afirmativo, como eu faria para adicionar todas as migrações que tenho em meus aplicativos e adicioná-las ao .gitignorearquivo?

Michael Smith
fonte

Respostas:

138

Citando a documentação de migração do Django :

Os arquivos de migração para cada aplicativo residem em um diretório de “migrações” dentro desse aplicativo e são projetados para serem comprometidos e distribuídos como parte de sua base de código. Você deve criá-los uma vez na máquina de desenvolvimento e, em seguida, executar as mesmas migrações nas máquinas dos seus colegas, nas máquinas de teste e, eventualmente, nas máquinas de produção.

Se você seguir este processo, não deverá obter nenhum conflito de mesclagem nos arquivos de migração.

Ao mesclar ramos de controle de versão, você ainda pode encontrar uma situação em que tenha múltiplas migrações baseadas na mesma migração pai, por exemplo, se para diferentes desenvolvedores introduziram uma migração simultaneamente. Uma maneira de resolver essa situação é introduzir uma _merge_migration_. Freqüentemente, isso pode ser feito automaticamente com o comando

./manage.py makemigrations --merge

que irá introduzir uma nova migração que depende de todas as migrações de cabeçalhos atuais. Claro que isso só funciona quando não há conflito entre as migrações do cabeçote, caso em que você terá que resolver o problema manualmente.


Dado que algumas pessoas aqui sugeriram que você não deveria comprometer suas migrações para o controle de versão, gostaria de expandir os motivos pelos quais você realmente deveria fazer isso.

Primeiro, você precisa de um registro das migrações aplicadas aos seus sistemas de produção. Se você implantar mudanças na produção e quiser migrar o banco de dados, precisará de uma descrição do estado atual. Você pode criar um backup separado das migrações aplicadas a cada banco de dados de produção, mas isso parece desnecessariamente complicado.

Em segundo lugar, as migrações geralmente contêm código personalizado escrito à mão. Nem sempre é possível gerá-los automaticamente com ./manage.py makemigrations.

Terceiro, as migrações devem ser incluídas na revisão do código. Eles são mudanças significativas em seu sistema de produção e há muitas coisas que podem dar errado com eles.

Resumindo, se você se preocupa com seus dados de produção, verifique suas migrações para o controle de versão.

Sven Marnach
fonte
24
Nós, uma equipe de desenvolvedores, também temos exatamente o mesmo problema. Se um membro executar makemigrations some_app, não apenas os modelos sob o controle desse membro serão afetados, mas também outros modelos relacionados serão afetados. Ou seja, os arquivos de migração (00 * _ *) em outros aplicativos serão alterados. E isso causa muitos problemas de conflito durante o push ou pull do GitHub. Como atualmente nosso sistema ainda não está pronto para produção, ficamos apenas com .gitignoreo arquivo de migração. Ainda não sabemos como resolver quando o sistema entrar em produção. Alguém tem alguma solução?
Randy Tang,
2
Então, se eu bem entendi, você tem que puxar as migrações do seu projeto. Quando você muda algo, você tem que fazer uma migração local. Empurre-o novamente e o buildserver fará a migração? (Muito importante, claro, todos têm as boas versões)
lvthillo
nunca usamos migrações de Django. todos se conectam a um banco de dados de teste central, se uma mudança for necessária, ela é feita manualmente no nível do banco de dados quando necessário. Este método funciona bem se o sistema estiver maduro o suficiente quando não precisar de muitas atualizações do esquema do banco de dados.
gurel_kaynak
@ yltang52 No momento, estamos tentando descobrir isso também. Você pode compartilhar alguma ideia? Acho que uma vez que você vai para a produção, você não tem escolha a não ser manter essas migrações para permitir patches mais fáceis e controle de versão mais fácil em geral. Também me pergunto o que você faz com os dados de estado inicial (como configurações armazenadas em db). Como você os mantém?
Daniel Dubovski
3
Não acho que você deva colocar os arquivos de migração no repo. Isso estragará os estados de migração no ambiente de desenvolvimento de outra pessoa e em outros ambientes de produção e estágio. (consulte o comentário de Sugar Tang para exemplos). O arquivo de modelos de rastreamento é suficiente.
Diansheng
19

Você pode seguir o processo abaixo.

Você pode executar makemigrationslocalmente e isso cria o arquivo de migração. Confirme este novo arquivo de migração para o repo.

Na minha opinião, você não deve rodar makemigrationsem produção. Você pode executar migrateem produção e verá que as migrações são aplicadas a partir do arquivo de migração que você confirmou localmente. Desta forma, você pode evitar todos os conflitos.

IN LOCAL ENV , para criar os arquivos de migração,

python manage.py makemigrations 
python manage.py migrate

Agora envie esses arquivos recém-criados, algo como abaixo.

git add app/migrations/...
git commit -m 'add migration files' app/migrations/...

NA PRODUÇÃO ENV , execute apenas o comando abaixo.

python manage.py migrate
Super Nova
fonte
3
Na minha opinião, o arquivo de migração só deve fazer parte do repo depois que o aplicativo for implantado. Isso contou como migrações iniciais. Se o aplicativo ainda estiver em desenvolvimento pesado, podemos ignorá-lo com segurança. Mas assim que entrar no ar. É isso aí! Esse é o sinal de que as migrações devem ser colocadas no repo. Todos os outros membros precisam seguir essas migrações e colocar as suas quando necessário
swdev
1
Muito bom ponto para executar apenas migratee NUNCA makemigrationspara migrações confirmadas. Nunca pensei nisso.
polarizar
9

Citação dos documentos de 2018, Django 2.0. (dois comandos separados = makemigrationse migrate)

A razão pela qual existem comandos separados para fazer e aplicar migrações é porque você enviará migrações para seu sistema de controle de versão e as enviará com seu aplicativo; eles não apenas tornam seu desenvolvimento mais fácil, mas também podem ser usados ​​por outros desenvolvedores e em produção.

https://docs.djangoproject.com/en/2.0/intro/tutorial02/

Techkuz
fonte
7

TL; DR: confirme migrações, resolva conflitos de migração, ajuste seu fluxo de trabalho git.

Parece que você precisa ajustar seu fluxo de trabalho git , em vez de ignorar os conflitos.

Idealmente, cada novo recurso é desenvolvido em um branch diferente e mesclado de volta com uma solicitação de pull .

Os PRs não podem ser mesclados se houver um conflito, portanto, quem precisa mesclar seu recurso precisa resolver o conflito, incluindo as migrações. Isso pode exigir coordenação entre equipes diferentes.

Porém, é importante confirmar os arquivos de migração! Se surgir um conflito, o Django pode até ajudá-lo a resolver esses conflitos ;)

Sdra
fonte
Essa é a resposta certa. Um fluxo de trabalho de sistema de controle de versão operacional parece estar implícito na documentação do django, mas é fundamental.
Eric
3

Não consigo imaginar por que você estaria tendo conflitos, a menos que esteja editando as migrações de alguma forma? Isso geralmente termina mal - se alguém perder alguns commits intermediários, ele não estará atualizando da versão correta e sua cópia do banco de dados será corrompida.

O processo que sigo é muito simples - sempre que você altera os modelos de um aplicativo, você também efetua uma migração, e então essa migração não muda - se você precisa de algo diferente no modelo, então você muda o modelo e envia um nova migração junto com suas mudanças.

Em projetos greenfield, muitas vezes você pode excluir as migrações e começar do zero com uma migração 0001_ ao lançar, mas se você tiver o código de produção, não pode (embora possa reduzir as migrações em um).

Anthony Briggs
fonte
Excelente ponto sobre começar do zero com 0001 para lançamento.
andho
3

A solução normalmente usada é que, antes que qualquer coisa seja mesclada com o mestre, o desenvolvedor deve puxar quaisquer alterações remotas. Se houver um conflito nas versões de migração, ele deve renomear sua migração local (a remota foi executada por outros desenvolvedores e, potencialmente, em produção), para N + 1.

Durante o desenvolvimento, pode ser normal apenas não enviar migrações (não adicione um ignore, apenas não faça addisso). Mas, depois de entrar em produção, você precisará deles para manter o esquema em sincronia com as alterações do modelo.

Em seguida, você precisa editar o arquivo e alterar dependenciespara a versão remota mais recente.

Isso funciona para migrações de Django, bem como outros aplicativos semelhantes (sqlalchemy + alembic, RoR, etc).

WhyNotHugo
fonte
1

Ter um monte de arquivos de migração no git é uma bagunça. Há apenas um arquivo na pasta de migração que você não deve ignorar. Esse arquivo é o arquivo init .py. Se você ignorá-lo, o python não procurará mais submódulos dentro do diretório, portanto, qualquer tentativa de importar os módulos falhará. Portanto, a questão deve ser como ignorar todos os arquivos de migração, exceto init .py? A solução é: Adicione '0 * .py' aos arquivos .gitignore e ele fará o trabalho perfeitamente.

Espero que isso ajude alguém.

Gizachew Soboksa
fonte
1

Gitignore as migrações, se você tiver bancos de dados separados para o ambiente de desenvolvimento, teste e produção. Para dev. finalidades Você pode usar o banco de dados sqlite local e brincar com as migrações localmente. Eu recomendo que você crie quatro branches adicionais:

  1. Mestre - Limpe o código novo sem migrações. Ninguém está conectado a este ramo. Usado apenas para revisões de código

  2. Desenvolvimento - desenvolvimento diário. Push / pull aceito. Cada desenvolvedor está trabalhando no banco de dados sqlite

  3. Cloud_DEV_env - ambiente DEV de nuvem / servidor remoto. Puxe apenas. Mantenha as migrações localmente na máquina, que é usada para a implantação de código e migrações remotas do banco de dados Dev

  4. Cloud_STAG_env - ambiente STAG de nuvem / servidor remoto. Puxe apenas. Mantenha as migrações localmente na máquina, que é usado para a implantação de código e migrações remotas do banco de dados Stag

  5. Cloud_PROD_env - ambiente DEV de nuvem / servidor remoto. Puxe apenas. Mantenha as migrações localmente na máquina, que é usada para a implantação de código e migrações remotas do banco de dados Prod

Observações: 2, 3, 4 - as migrações podem ser mantidas em repositórios, mas deve haver regras rígidas de mesclagem de solicitações pull, então decidimos encontrar uma pessoa, responsável pelas implantações, para que a única pessoa que tenha todos os arquivos de migração - nossa implantação -er. Ele mantém as migrações de banco de dados remotas cada vez que temos alguma mudança nos modelos.

Yevhen Dyachenko
fonte
-3

Resposta curta , proponho excluir migrações no repo. Após a fusão do código, basta executar ./manage.py makemigrationse está tudo pronto.

Resposta longa Não acho que você deva colocar os arquivos de migração no repo. Isso estragará os estados de migração no ambiente de desenvolvimento de outra pessoa e em outros ambientes de produção e estágio. (consulte o comentário de Sugar Tang para exemplos).

No meu ponto de vista, o objetivo das migrações do Django é encontrar lacunas entre os estados do modelo anterior e os novos estados do modelo e, em seguida, serializar a lacuna. Se o seu modelo mudar após a fusão do código, você pode simplesmente fazer makemigrationspara descobrir a lacuna. Por que você deseja mesclar manualmente e com cuidado outras migrações quando pode fazer o mesmo automaticamente e sem erros? A documentação do Django diz,

Eles * (migrações) * são projetados para serem automáticos

; por favor, mantenha assim. Para mesclar migrações manualmente, você deve entender completamente o que os outros mudaram e qualquer dependência das mudanças. Isso é muito overhead e está sujeito a erros. Portanto, o arquivo de modelos de rastreamento é suficiente.

É um bom tópico no fluxo de trabalho. Estou aberto a outras opções.

Diansheng
fonte
4
Isso só funcionará para projetos de brinquedo e tem muitas desvantagens. Ele para de funcionar imediatamente para migrações escritas à mão, para serviços que usam vários servidores de aplicativos efêmeros (ou seja, qualquer aplicativo sério) e para aplicativos que consistem em muitos aplicativos Django, cada um com suas próprias migrações. E eu não entendo o que você está se referindo com "mesclar migrações manualmente" - manage.py makemigrations --mergefunciona de forma totalmente automática para mim.
Sven Marnach
@Sven Marnach, eu estava realmente trabalhando em aplicativos pequenos, mas sérios. E funciona para mim.
Diansheng