引用 Django migrations documentation:
每个应用程序的迁移文件位于该应用程序内部的“迁移”目录中,旨在提交到其代码库并作为其代码库的一部分分发。你应该在你的开发机器上做一次,然后在你同事的机器、你的登台机器,最后是你的生产机器上运行相同的迁移。
如果您遵循此过程,则不应在迁移文件中遇到任何合并冲突。
在合并版本控制分支时,您仍然可能会遇到基于同一个父迁移的多个迁移的情况,例如,如果不同的开发人员同时引入了一个迁移。解决这种情况的一种方法是引入 merge_migration。通常这可以使用命令自动完成
./manage.py makemigrations --merge
这将引入一个依赖于所有当前头部迁移的新迁移。当然,这仅在头部迁移之间没有冲突时才有效,在这种情况下,您将不得不手动解决问题。
鉴于这里的一些人建议您不应该将迁移提交给版本控制,我想详细说明您实际上应该这样做的原因。
首先,您需要记录应用于生产系统的迁移。如果您将更改部署到生产并希望迁移数据库,则需要对当前状态的描述。您可以为应用于每个生产数据库的迁移创建单独的备份,但这似乎不必要地繁琐。
其次,迁移通常包含自定义的手写代码。并非总是可以使用 ./manage.py makemigrations
自动生成它们。
第三,迁移应该包含在代码审查中。它们是对您的生产系统的重大更改,并且它们可能会出现很多问题。
所以简而言之,如果你关心你的生产数据,请检查你的迁移到版本控制。
您可以按照以下流程进行操作。
您可以在本地运行 makemigrations
,这会创建迁移文件。将这个新的迁移文件提交到 repo。
在我看来,您根本不应该在生产环境中运行 makemigrations
。您可以在生产中运行 migrate
,您会看到迁移是从您从本地提交的迁移文件中应用的。这样你就可以避免所有的冲突。
在本地环境中,创建迁移文件,
python manage.py makemigrations
python manage.py migrate
现在提交这些新创建的文件,如下所示。
git add app/migrations/...
git commit -m 'add migration files' app/migrations/...
在 PRODUCTION ENV 中,仅运行以下命令。
python manage.py migrate
migrate
而从不运行 makemigrations
。从来没想过。
引自 2022 年文档 Django 4.0。 (两个单独的命令 = makemigrations
和 migrate
)
有单独的命令来进行和应用迁移的原因是因为您将迁移提交到您的版本控制系统并将它们与您的应用程序一起发布;它们不仅使您的开发更容易,而且还可供其他开发人员和生产环境使用。
https://docs.djangoproject.com/en/4.0/intro/tutorial02/
TL;DR:提交迁移,解决迁移冲突,调整你的 git 工作流。
感觉你需要调整你的 git 工作流程,而不是忽略冲突。
理想情况下,每个新功能都在不同的分支中开发,并与拉取请求合并回来。
如果存在冲突,则 PR 无法合并,因此需要合并他的功能的人需要解决冲突,包括迁移。这可能需要不同团队之间的协调。
提交迁移文件很重要!如果发生冲突,Django might even help you solve those conflicts ;)
通常使用的解决方案是,在将任何内容合并到 master 之前,开发人员必须拉取任何远程更改。如果迁移版本存在冲突,他应该将他的本地迁移(远程迁移已由其他开发人员运行,并且可能在生产中运行)重命名为 N+1。
在开发过程中,不提交迁移可能是可以的(尽管不要添加忽略,只是不要add
它们)。但是一旦您投入生产,您将需要它们以使模式与模型更改保持同步。
然后您需要编辑该文件,并将 dependencies
更改为最新的远程版本。
这适用于 Django 迁移,以及其他类似的应用程序(sqlalchemy+alembic、RoR 等)。
我无法想象为什么你会遇到冲突,除非你以某种方式编辑迁移?这通常会以糟糕的方式结束 - 如果有人错过了一些中间提交,那么他们将不会从正确的版本升级,并且他们的数据库副本将被损坏。
我遵循的过程非常简单 - 每当您更改应用程序的模型时,您也会提交迁移,然后迁移不会改变 - 如果您需要模型中的不同内容,那么您更改模型并提交新迁移以及您的更改。
在新建项目中,您通常可以删除迁移并在发布时使用 0001_ 迁移从头开始,但如果您有生产代码,则不能(尽管您可以将迁移压缩为一个)。
如果您有用于开发、暂存和生产环境的单独数据库,请忽略迁移。对于开发。目的您可以使用本地 sqlite DB 并在本地进行迁移。我建议您创建四个额外的分支:
Master - 无需迁移即可清洁新代码。没有人连接到这个分支。仅用于代码审查 开发 - 日常开发。推/拉接受。每个开发人员都在使用 sqlite DB Cloud_DEV_env - 远程云/服务器 DEV 环境。只拉。在机器本地保存迁移,用于开发数据库 Cloud_STAG_env - 远程云/服务器 STAG 环境的代码部署和远程迁移。只拉。将迁移保存在本地机器上,用于 Stag 数据库 Cloud_PROD_env - 远程云/服务器 DEV 环境的代码部署和远程迁移。只拉。在机器本地保留迁移,用于 Prod 数据库的代码部署和远程迁移
注意:2、3、4 - 迁移可以保存在 repos 中,但应该有严格的合并拉取请求的规则,所以我们决定找一个人来负责部署,所以唯一拥有所有迁移文件的人 - 我们的部署-呃。每次我们对模型进行任何更改时,他都会保留远程数据库迁移。
在 git 中有一堆迁移文件很麻烦。迁移文件夹中只有一个文件是您不应忽略的。该文件是 init.py 文件,如果忽略它,python 将不再在目录中查找子模块,因此任何导入模块的尝试都会失败。所以问题应该是如何忽略除了init.py之外的所有迁移文件?解决方案是:将 '0*.py' 添加到 .gitignore 文件,它可以完美地完成工作。
希望这可以帮助某人。
您应该将迁移视为数据库模式的版本控制系统。 makemigrations 负责将您的模型更改打包到单独的迁移文件中 - 类似于提交 - 并且 migrate 负责将这些更改应用于您的数据库。
每个应用程序的迁移文件位于该应用程序内部的“迁移”目录中,旨在提交到其代码库并作为其代码库的一部分分发。你应该在你的开发机器上做一次,然后在你同事的机器、你的登台机器,最后是你的生产机器上运行相同的迁移。
黄金法则:开发一次,全部迁移
简短回答 我建议在 repo 中排除迁移。代码合并后,只需运行 ./manage.py makemigrations
即可。
长答案我认为您不应该将迁移文件放入回购中。它会破坏其他人的开发环境和其他产品和阶段环境中的迁移状态。 (请参阅 Sugar Tang 的评论示例)。
在我看来,Django 迁移的目的是找到先前模型状态和新模型状态之间的差距,然后将差距序列化。如果代码合并后你的模型发生了变化,你可以简单地做makemigrations
找出差距。当您可以自动实现相同且无错误的迁移时,为什么还要手动小心地合并其他迁移? Django documentation 说,
他们*(迁移)*'被设计成大部分是自动的
;请保持这种状态。要手动合并迁移,您必须完全了解其他人已更改的内容以及更改的任何依赖性。这是很多开销并且容易出错。所以跟踪模型文件就足够了。
这是关于工作流程的一个很好的话题。我对其他选择持开放态度。
manage.py makemigrations --merge
对我来说完全自动工作。
makemigrations some_app
,不仅该成员控制的模型会受到影响,其他相关模型也会受到影响。也就是说,其他应用程序中的迁移文件(00*_*)将被更改。这会在向 GitHub 推送或从 GitHub 拉取时导致许多冲突问题。由于目前我们的系统尚未准备好投入生产,因此我们只需.gitignore
迁移文件。当系统投入生产时,我们仍然不知道如何解决它。有没有人有任何解决方案?