我应该在.gitignore文件中添加Django迁移文件吗?

问题:我应该在.gitignore文件中添加Django迁移文件吗?

我应该在文件中添加Django迁移.gitignore文件吗?

由于迁移冲突,我最近遇到了很多git问题,并且想知道是否应该将迁移文件标记为“忽略”。

如果是这样,我将如何添加我在应用程序中拥有的所有迁移并将它们添加到.gitignore文件中?

Should I be adding the Django migration files in the .gitignore file?

I’ve recently been getting a lot of git issues due to migration conflicts and was wondering if I should be marking migration files as ignore.

If so, how would I go about adding all of the migrations that I have in my apps, and adding them to the .gitignore file?


回答 0

引用Django迁移文档

每个应用程序的迁移文件都位于该应用程序内的“迁移”目录中,并被设计为提交至其代码库并作为其代码库的一部分进行分发。您应该在开发计算机上制作一次,然后在同事的计算机,登台计算机以及最终的生产计算机上运行相同的迁移。

如果遵循此过程,则迁移文件中不会出现任何合并冲突。

合并版本控制分支时,您仍然可能会遇到基于同一父级迁移的多个迁移的情况,例如,如果不同的开发人员同时引入了迁移。解决这种情况的一种方法是引入_merge_migration_。通常这可以通过以下命令自动完成

./manage.py makemigrations --merge

这将引入一个新的迁移,该迁移取决于当前的所有head迁移。当然,这仅在磁头迁移之间没有冲突时才有效,在这种情况下,您将必须手动解决问题。


鉴于这里有人建议您不要将迁移提交到版本控制,因此我想详细说明为什么您应该这样做。

首先,您需要记录应用于生产系统的迁移。如果将更改部署到生产中并想迁移数据库,则需要描述当前状态。您可以为应用到每个生产数据库的迁移创建单独的备份,但这似乎不必要。

其次,迁移通常包含自定义的手写代码。并非总是可以使用自动生成它们./manage.py makemigrations

第三,迁移应包含在代码审查中。它们是对您的生产系统的重大更改,很多事情都可能出错。

简而言之,如果您关心生产数据,请检查您向版本控制的迁移。

Quoting from the Django migrations documentation:

The migration files for each app live in a “migrations” directory inside of that app, and are designed to be committed to, and distributed as part of, its codebase. You should be making them once on your development machine and then running the same migrations on your colleagues’ machines, your staging machines, and eventually your production machines.

If you follow this process, you shouldn’t be getting any merge conflicts in the migration files.

When merging version control branches, you still may encounter a situation where you have multiple migrations based on the same parent migration, e.g. if to different developers introduced a migration concurrently. One way of resolving this situation is to introduce a _merge_migration_. Often this can be done automatically with the command

./manage.py makemigrations --merge

which will introduce a new migration that depends on all current head migrations. Of course this only works when there is no conflict between the head migrations, in which case you will have to resolve the problem manually.


Given that some people here suggested that you shouldn’t commit your migrations to version control, I’d like to expand on the reasons why you actually should do so.

First, you need a record of the migrations applied to your production systems. If you deploy changes to production and want to migrate the database, you need a description of the current state. You can create a separate backup of the migrations applied to each production database, but this seems unnecessarily cumbersome.

Second, migrations often contain custom, handwritten code. It’s not always possible to automatically generate them with ./manage.py makemigrations.

Third, migrations should be included in code review. They are significant changes to your production system, and there are lots of things that can go wrong with them.

So in short, if you care about your production data, please check your migrations into version control.


回答 1

您可以按照以下过程进行操作。

您可以在makemigrations本地运行,这将创建迁移文件。提交此新的迁移文件以回购。

我认为您根本不应该makemigrations投入生产。您可以migrate在生产环境中运行,并且会看到从您从本地提交的迁移文件中应用了迁移。这样您可以避免所有冲突。

在本地环境中,要创建迁移文件,

python manage.py makemigrations 
python manage.py migrate

现在提交这些新创建的文件,如下所示。

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

在生产环境中,仅运行以下命令。

python manage.py migrate

You can follow the below process.

You can run makemigrations locally and this creates the migration file. Commit this new migration file to repo.

In my opinion you should not run makemigrations in production at all. You can run migrate in production and you will see the migrations are applied from the migration file that you committed from local. This way you can avoid all conflicts.

IN LOCAL ENV, to create the migration files,

python manage.py makemigrations 
python manage.py migrate

Now commit these newly created files, something like below.

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

IN PRODUCTION ENV, run only the below command.

python manage.py migrate

回答 2

引用2018年文档Django 2.0。(两个单独的命令= makemigrationsmigrate

之所以有单独的命令来进行和应用迁移,是因为您会将迁移提交到版本控制系统,并随应用程序一起交付;它们不仅使您的开发更加容易,而且还可以被其他开发人员和生产环境使用。

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

Quote from the 2018 docs, Django 2.0. (two separate commands = makemigrations and migrate)

The reason that there are separate commands to make and apply migrations is because you’ll commit migrations to your version control system and ship them with your app; they not only make your development easier, they’re also useable by other developers and in production.

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


回答 3

TL; DR:提交迁移,解决迁移冲突,调整git工作流程。

感觉就像您需要调整git工作流程,而不是忽略冲突。

理想情况下,每个新功能都在不同的分支中开发,并与拉取请求合并回去。

如果存在冲突,则无法合并PR,因此需要合并其功能的人员需要解决冲突,包括迁移。这可能需要不同团队之间的协调。

提交迁移文件很重要!如果发生冲突,Django甚至可以帮助您解决那些冲突 ;)

TL;DR: commit migrations, resolve migration conflicts, adjust your git workflow.

Feels like you’d need to adjust your git workflow, instead of ignoring conflicts.

Ideally, every new feature is developed in a different branch, and merged back with a pull request.

PRs cannot be merged if there’s a conflict, therefore who needs to merge his feature needs to resolve the conflict, migrations included. This might need coordination between different teams.

It is important though to commit migration files! If a conflict arises, Django might even help you solve those conflicts ;)


回答 4

我无法想象为什么会出现冲突,除非您以某种方式编辑迁移?通常情况下,这很糟糕-如果有人错过了一些中间提交,那么他们就不会从正确的版本升级,并且他们的数据库副本也会被破坏。

我遵循的过程非常简单-每当您更改应用程序的模型时,您也会提交迁移,然后迁移不会改变 -如果您需要模型中的其他内容,则可以更改模型并提交新的迁移以及您的更改。

在未开发项目中,您通常可以删除迁移,并在发布时从0001_开始重新迁移,但是如果您具有生产代码,则不能(尽管可以将迁移压缩为一个)。

I can’t imagine why you would be getting conflicts, unless you’re editing the migrations somehow? That usually ends badly – if someone misses some intermediate commits then they won’t be upgrading from the correct version, and their copy of the database will be corrupted.

The process that I follow is pretty simple – whenever you change the models for an app, you also commit a migration, and then that migration doesn’t change – if you need something different in the model, then you change the model and commit a new migration alongside your changes.

In greenfield projects, you can often delete the migrations and start over from scratch with a 0001_ migration when you release, but if you have production code, then you can’t (though you can squash migrations down into one).


回答 5

通常使用的解决方案是,在将任何东西合并到母版之前,开发人员必须拉动任何远程更改。如果迁移版本存在冲突,则他应将其本地迁移(远程迁移已由其他开发人员运行,并且有可能在生产环境中)重命名为N + 1。

在开发过程中,不提交迁移就可以了(尽管不要添加忽略,只是不要添加忽略add)。但是一旦投入生产,就需要使用它们,以使模式与模型更改保持同步。

然后,您需要编辑文件,并将其更改dependencies为最新的远程版本。

这适用于Django迁移以及其他类似应用程序(sqlalchemy + alembic,RoR等)。

The solution usually used, is that, before anything is merged into master, the developer must pull any remote changes. If there’s a conflict in migration versions, he should rename his local migration (the remote one has been run by other devs, and, potentially, in production), to N+1.

During development it might be okay to just not-commit migrations (don’t add an ignore though, just don’t add them). But once you’ve gone into production, you’ll need them in order to keep the schema in sync with model changes.

You then need to edit the file, and change the dependencies to the latest remote version.

This works for Django migrations, as well as other similar apps (sqlalchemy+alembic, RoR, etc).


回答 6

在git中有一堆迁移文件很麻烦。迁移文件夹中只有一个文件,您不应忽略。该文件是init .py文件,如果忽略它,python将不再在目录内寻找子模块,因此任何导入模块的尝试都会失败。所以问题应该怎么忽略所有迁移文件,但初始化的.py?解决方案是:将’0 * .py’添加到.gitignore文件中,即可完美完成工作。

希望这对某人有帮助。

Having a bunch of migration files in git is messy. There is only one file in migration folder that you should not ignore. That file is init.py file, If you ignore it, python will no longer look for submodules inside the directory, so any attempts to import the modules will fail. So the question should be how to ignore all migration files but init.py? The solution is: Add ‘0*.py’ to .gitignore files and it does the job perfectly.

Hope this helps someone.


回答 7

如果您具有用于开发,登台和生产环境的单独的数据库,则忽略迁移。对于开发人员。目的您可以使用本地sqlite DB并在本地进行迁移。我建议您另外创建四个分支:

  1. 主-清除新代码而不进行迁移。没有人连接到该分支。仅用于代码审查

  2. 开发-日常开发。接受推/拉。每个开发人员都在使用sqlite DB

  3. Cloud_DEV_env-远程云/服务器DEV环境。只拉。将迁移保留在本地计算机上,用于代码部署和Dev数据库的远程迁移

  4. Cloud_STAG_env-远程云/服务器STAG环境。只拉。将迁移保留在本地计算机上,该迁移用于Stag数据库的代码部署和远程迁移

  5. Cloud_PROD_env-远程云/服务器DEV环境。只拉。将迁移保留在本地计算机上,该迁移用于Prod数据库的代码部署和远程迁移

注意:2、3、4-迁移可以保存在存储库中,但是应该有合并合并拉取请求的严格规则,因此我们决定找一个负责部署的人员,所以唯一拥有所有迁移文件的人-我们的部署-嗯 每当我们对模型进行任何更改时,他都会保留远程数据库迁移。

Gitignore the migrations, if You have separate DBs for Development, Staging and Production environment. For dev. purposes You can use local sqlite DB and play with migrations locally. I would recommend You to create four additional branches:

  1. Master – Clean fresh code without migrations. Nobody is connected to this branch. Used for code reviews only

  2. Development – daily development. Push/pull accepted. Each developer is working on sqlite DB

  3. Cloud_DEV_env – remote cloud/server DEV environment. Pull only. Keep migrations locally on machine, which is used for the code deployment and remote migrations of Dev database

  4. Cloud_STAG_env – remote cloud/server STAG environment. Pull only. Keep migrations locally on machine, which is used for the code deployment and remote migrations of Stag database

  5. Cloud_PROD_env – remote cloud/server DEV environment. Pull only. Keep migrations locally on machine, which is used for the code deployment and remote migrations of Prod database

Notes: 2, 3, 4 – migrations can be kept in repos but there should be strict rules of pull requests merging, so we decided to find a person, responsible for deployments, so the only guy who has all the migration files – our deploy-er. He keeps the remote DB migrations each time we have any changes in Models.


回答 8

简短答案 我建议排除回购中的迁移。代码合并后,只需运行即可./manage.py makemigrations

长答案 我不认为您应该将迁移文件放入存储库中。它将破坏其他人的开发环境以及其他产品和阶段环境中的迁移状态。(有关示例,请参见Sugar Tang的评论)。

以我的观点,Django迁移的目的是找到先前模型状态和新模型状态之间的差距,然后序列化该差距。如果您的模型在代码合并后发生更改,则可以简单makemigrations地找出差距。当您可以自动实现相同且无错误的迁移时,为什么要手动仔细合并其他迁移?Django文档说,

它们*(迁移)*被设计为自动的

; 请保持这种方式。要手动合并迁移,您必须完全了解其他更改和更改的任何依存关系。这会产生很多开销,而且容易出错。因此,跟踪模型文件就足够了。

这是工作流程中的一个好话题。我愿意接受其他选择。

Short answer I propose excluding migrations in the repo. After code merge, just run ./manage.py makemigrations and you are all set.

Long answer I don’t think you should put migrations files into repo. It will spoil the migration states in other person’s dev environment and other prod and stage environment. (refer to Sugar Tang’s comment for examples).

In my point of view, the purpose of Django migrations is to find gaps between previous model states and new model states, and then serialise the gap. If your model changes after code merge, you can simple do makemigrations to find out the gap. Why do you want to manually and carefully merge other migrations when you can achieve the same automatically and bug free? Django documentation says,

They*(migrations)*’re designed to be mostly automatic

; please keep it that way. To merge migrations manually, you have to fully understand what others have changed and any dependence of the changes. That’s a lot of overhead and error prone. So tracking models file is sufficient.

It is a good topic on the workflow. I am open to other options.