我一直在浏览有关使用 Flask-Migrate
进行数据库迁移的 flask
开发的 stackoverflow 帖子。然而,我仍然不满意并继续思考用于管理开发和部署服务器的数据库迁移的最佳实践。
到目前为止我学到了什么
Miguel 本人建议 in another post ,
The ideal solution is that you generate an initial migration for your db schema as it was the day you started tracking migrations with Flask-Migrate and Alembic. ... Just create a separate empty database (leave your real db alone), configure your app to use the empty database, and then generate a migration. This migration will have the entire schema. Once you have that migration generated, get rid of the empty database and restore your configuration back to the real db.
上面的实践要求我在部署服务器中创建两个数据库,一个是虚拟数据库,我在其中执行两个命令:
flask db migrate # to empty dummy database
# then get rid of dummy database
# then change config (e.g. DATABASE_URI) to real deployment database
flask db upgrade # then upgrade the real database
我的问题仍然存在
- 在使用一些“活鱼”(实际数据已经填充到生产数据库)的部署/生产环境中处理数据库迁移时,真正的最佳做法是什么。我的问题不必特定于
Flask-Migrate
,我有时会在 Django 中处理这个问题,而在 Flask 中更常见,最后,我必须将迁移脚本完全重置为初始状态。我希望来自不同技术栈的人能理解我。 - 在新容器上部署时,我目前的做法是从开发中复制 flask 的迁移脚本文件夹,然后立即执行
flask db upgrade
。数据库中的表是否需要先存在?upgrade
命令是否保证像db.create_all()
一样执行创建?
注意:问题 2 是 Flask-Migrate
特定的。我对此表示怀疑的原因是因为很少在新容器上,我在 flask db upgrade
上遇到奇怪的错误:
Cannot create User table. Table already existed...
虽然之前在新容器中没有表设置,但我记得不久前我使用 Docker 在本地部署我的应用程序时发生过这种情况。还有一次,flask db upgrade
没有执行任何表创建,这很奇怪。请注意,我之前从未在新容器或开发中使用/调用过 db.create_all()
。
2021 年 3 月 25 日更新
一年过去了,现在我经常要处理这类问题。确实有许多不同的方式来执行数据库迁移,这个问题不仅仅与 Flask Migrate 相关。
任何需要关系 DBMS 作为其存储的网络应用程序开发人员(Go、Python、Ruby 等)都需要考虑如何提供与以前的数据库始终向后兼容的迁移脚本。
大多数时候,您的代码应用程序需要随着数据库迁移的变化而变化,但这并不意味着迁移必须与应用程序部署相结合。这取决于您的开发运营政策。
根据经验:
- 有一个上下脚本
- Up 脚本不应包含删除列或表。如果表的一列已过时,请在迁移成功后手动将其删除,旧的应用程序实例将推出,并且新迁移 + 应用程序代码的一切都是稳定的。
- 在 up 脚本中进行更改是可以的,但请注意,更改列名或数据类型是不兼容的。小心轻放。您可以创建新列,将旧列中的数据转换为新列,然后删除旧列。或者停机时间没关系,只需花时间部署与新数据库架构兼容的新应用程序。
- 下行脚本不应包含创建、插入或更改。
最佳答案
我认为您部分误解了您引用的评论,或者可能没有看到完整的答案。
迁移总是在您的开发数据库中生成。生产与生成迁移无关。
如果你有一个现有的数据库并且你想生成一个初始迁移,那么这个过程是:
- 创建一个空数据库
- 将应用配置为使用这个空数据库
- 运行
flask db migrate
生成初始迁移 - 切换回原来的数据库
- 在您的所有数据库(开发、生产等)中运行
flask db stamp head
以将它们标记为已升级 - 删除空数据库
- 从现在开始,您可以正常迁移和升级数据库。
关于你的第二个问题,答案是肯定的。 Alembic(通过 Flask-Migrate)在新表不存在时创建新表。
关于flask - 在开发和部署中使用 Flask-Migration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59490965/