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