从Git自动迁移数据库一年

2020-08-04 06:48:55

在过去一年多的时间里,在我的大部分个人工作中,我使用了一个名为Automig的工具来自动将我的SQL模式更改转换为可以应用于DB的增量(即插即用-我编写了它)。

我讨厌编写迁移,因为感觉计算机应该知道如何完成工作,而且通常不能保证迁移产生与您的“schema.sql”或ORM定义等同的内容。

(SQLAlChemy的alembic有一个自动生成功能,可以将正在运行的DB与您的ORM规范进行比较;我不讨厌这一点,但我也不喜欢它。这似乎意味着您必须连接到prod DB才能生成迁移)。

我已经1年多没有写过移民了,而且我也不喜欢写移民,这是一个胜利。

只要你相信这个工具知道它在做什么,你就可以打开schema.sql文件(或者任何你选择给你自己命名的文件),得到一个模式,它既是数据库应该拥有什么的可读文档,也是数据库实际拥有什么的可靠指示器。

跨不同语言的标准工具我在不同的python和golang项目上使用过Automig,它无关紧要,它与代码库中的任何设计或工具决策无关。Automig不是一个标准工具,但如果它是标准工具,它将是一个可移植的技能集。

没有杂乱的迁移目录。更多的是个人卫生决定,而不是合法的抱怨,但迁移目录不是我的最爱;数百个做得很少的文件。Automig在重新初始化方面也更快,因为您可以从GIT Head开始,而不是应用过去36个月的数百个更改。

把复杂的东西变成简单但几乎一样好的东西。有缺点(见下文),但是有一堆与迁移相关的工作我不再考虑了。我不再害怕添加数据库列或索引。如果因为工具更简单、更具说明性而降低了我的能力,这是一种权衡,但这是我一直快乐地生活在一起的。

不支持数据迁移。Automig擅长模式迁移,但没有一种简单的方法来转换列或在数据库上运行代码。该工具在路线图中对此有一个答案。根据我自己的需要,我可以通过使用默认值执行两步迁移来解决此问题。

对于较大的用户,数据迁移涉及很多设计(例如,请参阅GitHub的GH-OST工具)。将来,我认为迁移应该是数据库中的原生功能-您应该上载模式并指定迁移是预先运行还是在读取时运行。而且我们不应该将类型与存储位置捆绑在一起。

当出现问题时,我必须修复它。这是对使用我维护的工具的50%的抱怨,也是唯一的用户。但50%的合法观点是,“声明性差异”工具比您用SQL自己编写的迁移具有更多的逻辑。运行任意SQL给了您很大的灵活性,并给了您无限的自由来选择不兼容的方言。

与ORM集成的额外提升。Automig可以从schema.sql生成SQLAlChemy定义,但仅此而已。如果您使用单一语言/框架,在ORM中定义DB可能比使用SQL指定它更有用。

方言支持并非易事,当我在一些项目中从postgres切换到sqlite时,支持不同的方言是一件很痛苦的事情,我遇到了对事务性DDL的不同支持。

分支冲突问题+重建。任何非线性的GIT历史记录都可能是错误的来源。Automig有一个--不透明的开关来解决这些问题,但是手动指定的迁移在分支上可能更好,特别是当您需要支持无序更改时。我没有遇到这些问题,因为我是单独的代码库,但我可以看到有时从非主分支部署的大型团队中存在问题。

迁移生产涉及到前期工作。如果您使用主要的后端语言/框架来运行迁移,则很容易。Automig有额外的要求:它需要捆绑.git文件夹(即整个历史)。当我在lambda上运行这项工作时,我还必须捆绑一个git二进制文件,而我的ubuntu二进制文件不起作用。我花了一整天的时间学习如何静态构建git,然后才意识到我可以只捕获centos。好消息是,每个平台只需完成这项工作一次。

测试很烦人,因为Automig只对已提交的更改起作用,所以我有时不得不做几轮git提交--在工作之前进行修改。

列顺序。Automig不保证列顺序(它在a之后添加列,但不添加列b)。这导致了备份/恢复的问题。这是该工具的问题,但不一定是使用git+sql作为真实源的方法的问题。

奇怪的解析器。我的解析器库很容易混淆,特别是大小写和看起来像关键字的名称。而且它是多层的(我使用python sqlparse,然后包装它),即jank.这不是我使用的具体工具的问题,但它会带来问题。