为什么是SQL呢?我已经将近十年没有接触过MongoDB世界了(真是松了一口气)。卡桑德拉从来没有真的穿过我的路。任何理智的团队都有自己的Elasticsearch迁移工具,叫做从头开始创建所有索引,这里没有什么有趣的可说的。我唯一接触过的另一个数据库是Datonomic,他们有一些关于迁移的非常有趣的事情要说,我不会对此发表评论。
不管怎样,说到这个话题。为什么会存在基于ORM的迁移工具?让我们看一组项目本身的描述来寻找线索:
Django:迁移是Django传播您对模型所做更改(添加字段、删除模型等)的方式。添加到您的数据库架构中。它们被设计成基本上是自动的,但你需要知道什么时候移民,什么时候运行,以及你可能会遇到的常见问题。
Ruby onRails:迁移是一种方便的方式,可以随着时间的推移以一致和简单的方式改变您的数据库模式。它们使用Ruby DSL,这样您就不必手动编写SQL,从而允许您的模式和更改独立于数据库。
我曾亲自使用Django迁移和浏览文档来实现其他一些工具:Alembic、RoR迁移、Sequelize、TypeORM。
数据库独立性对于一些Django风格的应用程序当然很有用。它们本质上是定义它们自己的模型并可以在新版本中更新它们的库。我想到的是用户管理库,比如django-allauth或python-Social-auth。如果没有内置的迁移,我们将不得不阅读它们的更改日志,并通过手形的穴居人来应用模式更改。
我现在认为,任何Django风格的应用程序只对几个月内组装在一起的短项目有用。在长期项目中,他们通常遇到的障碍比帮助的要多得多。
绝大多数Web应用程序和产品都运行在一个数据库上,不要从Oracle切换到MySQL,再切换到PostgreSQL,然后再切换回来。
这些工具致力于自动生成迁移。这个过程是这样的:阅读文档,在模型声明中添加一个字段,运行一些命令,然后砰!我们已经完成了迁移,现在不必编写ALTER TABLE TABLE CREATE COLUMN,所以我用一分钟来写一行,用一两个小时来阅读文档和使用这个新工具。令人着迷的体验,我希望它至少能为我们节省更多的时间。
一周后,我重命名了一些字段或表,现在该工具想要删除该字段并创建另一个字段。我想我必须回去阅读更多的文档,才能记住如何指示工具实际重命名一个字段,而不是丢弃它并创建一个新字段。我真的希望避免那么多地编写ALTER TABLE吗?
几周过去了,我对工具有了更多的经验,记住了命令和要传递的标志,我学会了如何重命名这个和那个,花了一些时间调试我的迁移。在一个简单的ALTER TABLE之上的小时数和小时数。
现在,我需要在一个大型数据库上进行一些非常重要的迁移。例如,它是创建几个字段、用信息填充它们、创建附加索引、删除旧字段和索引的组合。在这种情况下,我通常将Postgres shell打开到本地数据库,打开一个事务,然后像REPL中的代码一样进行迁移。开始,然后创建一些列,用信息填充它们,选择以检查它是否正确。不,在更新过程中搞砸了一些案例,丢失了大约三分之一的相关信息。没问题,请回滚,粘贴工作部分,然后重试。
就这些自动化工具而言,在我完成所有这些工作之后,我必须重新阅读它们相当大量的文档,因为我忘记了一些东西,并且将SQL移植到了它们的语法中。或者,我现在应该直接使用原始SQL吗?从一开始就使用这个工具的意义是什么?
然后,我们将还不太了解SQL的初级成员添加到团队中。通过该工具,EasierTask是自动化的,他们只需阅读几个小时的文档,而不需要学习如何用SQL编写实际的ALTER TABLE,以及它可以在事务内回滚等等。
而现在,当低年级学生面临更复杂的问题时,他们完全缺乏发展迁移的技能,需要攀登的墙要陡峭得多。因此,他们坐在电脑前,盯着文档看了几个小时,这本来是一项现在应该可以接近的任务。
另一件事是,许多工具都有降级迁移。降级移民是个谎言!我删除了一个带有NOT NULL的列,现在怎么办?迁移现在是不可逆转的。如果我真的需要在生产环境中恢复可逆迁移,我将编写另一个向前迁移。我在十多年的时间里做到了零次。
在开发期间,我可以切换具有不同模式的分支,它们可能是不兼容的。当然,然后我必须手动进行向后迁移,甚至从跟踪表中删除一行。在过去的五年里,我这样做过几次。无处不在的降级迁移能为我节省这5分钟吗?毋庸置疑,这种不兼容性通常源于不可逆转的变化,比如删除NOT NULL列,而迁移工具只会发出不可逆转的错误。
另一个次要问题是,有时迁移需要很长时间。不是一秒或两秒-它可以在生产过程中持续几个小时。我不希望此迁移在我的部署过程中自动开始(我的配置项会认为它已死亡,等等),但它应该是所有迁移的常规部分,因此在本地开发人员安装时,这些迁移只需按常规进行迁移即可。提取SQL脚本的一部分并单独运行,要比提取用Python编写的迁移脚本的一部分并单独运行要容易得多。
几年前,当我继承了一个带工作迁移的Django项目时,我已经用了几个月的疯狂,然后又换回了一个简单的基于SQL的系统。
虽然这些工具使最简单的案件自动化,但它们使更复杂的案件变得更加困难。不幸的是,这是姜戈地区非常常见的陷阱,我听说RoR也差不多。
我个人使用一种名为Nomad的简单工具。我认为任何支持纯SQL迁移、迁移之间有依赖关系并且不需要写下级别的工具都是可以接受的。