[英]Django: How to keep code and database sync'ed when deploying on Heroku?
假设我们有一个名为Alpha的 Django 项目。 在将 Django 项目部署到 Heroku 之前,开发人员在他们的开发环境中进行 Alpha 测试。Procfile 可能类似于:
release: python manage.py migrate
web: python -m gunicorn wsgi:application
当开发人员尝试部署新版本的 Alpha 时,该项目将与其迁移文件一起交付(如推荐的那样)。 部署结束时,Heroku会执行release
语句python manage.py migrate
,对数据库进行所有相关更改。 因为发布是整个部署过程的一部分,所以如果失败则不会部署新代码。
然而......虽然代码将恢复到部署之前的状态(如预期的那样),但对 Heroku 数据库的潜在更改将是永久性的。 例如,我们假设新版本有三个新的迁移:
0011
0012
0013
前两次迁移正确执行,数据库相应更改。 它们也被添加到数据库表django_migrations
中。 然而,最后一个包含一个问题(例如,它定义了阶段数据不遵守的约束)。
在这种情况下,Heroku 上的代码( /migrations/
和models.py
)和 Heroku 上的数据库现在严重不同步:实际上,数据库反映了其迁移甚至不存在于代码存储库中的更改。 这会产生各种各样的问题。
如何防止在这个谓词中发现自己并确保代码和数据在阶段和产品上始终 100% 同步?
后脚本
Heroku在其文档中包含以下片段:
使用事务进行数据库迁移
执行数据库迁移时,始终使用事务。 事务确保在将更改提交到数据库之前所有迁移操作都成功,从而最大限度地减少在发布阶段部分迁移失败的可能性。 如果在发布阶段数据库迁移失败(即迁移命令以非零状态退出),则不会部署新版本。 如果未使用事务,这可能会使数据库处于部分迁移的状态 state。我们建议使用 heroku 运行而不是发布阶段来进行架构/数据更正。
正如您引用的文档所说,在事务中进行迁移是个好主意。 Django 默认使用支持它的数据库执行此操作真是个好主意。
但这仅对一次迁移的 scope 有帮助:如果迁移0013
像您的示例一样失败,则它引入的更改将被回滚。 迁移0011
和0012
引入的更改不会被撤销。
要反转迁移0011
和0012
,您必须手动回滚,例如
python manage.py migrate myapp 0010
但是,由于如果部署失败,您的应用程序将运行以前的版本,因此您不能简单地heroku run
——Heroku 没有0011
和0012
的迁移文件。
这可能(至少部分)是 Heroku 文档说的原因
我们建议使用
heroku run
而不是发布阶段来进行架构/数据更正。
如果您删除迁移发布阶段命令,您可以像这样开始部署:
git push heroku main
heroku run python manage.py migrate
如果迁移失败,只需反转最后两次迁移,然后回滚到之前的版本:
heroku run python manage.py migrate myapp 0010
heroku releases:rollback
作为额外的预防措施,请考虑在开始升级之前将您的应用程序置于维护模式。 这将防止用户在您的网站可能处于不一致的 state 中时与您进行交互,例如,在您部署之后但在您应用迁移之前。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.