在软件开发过程中,确保代码与数据库模式的一致性是一个重要的挑战。本文将介绍一种实践方法,通过集成测试、Postgres容器化、版本控制和数据库模式版本控制来实现这一目标。
在介绍具体实践之前,先澄清一些关键术语的含义。
集成测试是软件测试的一个阶段,涉及将两个或多个模块组合在一起作为一个整体进行测试。在本文的上下文中,希望测试代码是否能够执行实际的数据库选择操作,即特定表中所需的所有列既在模式中也在代码中。在更复杂的情况下,这听起来像是“想要测试数据访问层是否能够对预生产环境中配置的数据源执行CRUD操作”。
在软件开发中,保持代码和模式严格耦合是一个好习惯,因此,*.sql脚本也应该进行版本控制。在团队中,使用适当的名称对它们进行排序(例如0_1 -> 0_2 -> 1_0 -> ...,可能使用一些语义版本控制约定),并将它们在DML(数据操作语言)脚本和DDL(数据定义语言)脚本之间进行分离。一个主要的好处是可以程序化地在任何地方重建模式,即在生产环境中,在持续集成管道的特定阶段,或者...在容器化的数据库中。
可以将其视为一个轻量级的虚拟机,它运行在操作系统中,并包含Postgres数据库。可以启动它,停止它,访问它,配置它,分发它,更重要的是,可以一次性地、程序化地并以集中的方式进行这些操作!
在团队中,分发了这种开发机器配置。正如所见,它是相当通用的,伙计们仍然可以浏览Facebook或阅读一些网球文章。
Bob是一位软件工程师。他想谈谈他的日常开发活动。一旦他在IDE中打开了项目simple_db_reader,他就会编写一些代码。在提交之前,他遵循以下步骤:
Bob运行sh ./docker_start_env.sh
来启动/重启他的本地Postgres。这很好,因为他不需要任何数据库安装,所有的*.sql脚本都位于simple_db_reader/sql中,并且会按字母顺序自动执行。此外,他可以使用PgAdmin访问一些表!这很棒,可以测试新的脚本!
Bob通过执行mvn package
来编译和测试他的代码。
Bob可以使用mvn exec:java
来运行jar包。
如果一切顺利,Bob会将其推送到一些远程分支。
Alice:几天前,在生产环境中发布了第一个版本(changeset da1d744)。可以通过以下命令查看它:
git checkout master
git checkout da1d744
sh ./docker_start_env.sh
mvn package
mvn exec:java
图2和图3显示了git日志中的da1d744检出以及代码和数据库模式之间的关系:
与此同时,DBA提出了一个关于数据库非规范化的变更请求,删除了地址表并添加了一个新的列zipcode到people中。重要的是要指出,这个请求对代码有很大的影响,所以需要修改集成测试AppTest.testDatabaseAccess,以确保代码库仍然与新模式对齐。一个新的分支addressesDenormalization被创建,Bob正在处理它:
git checkout addressesDenormalization
图4和图5显示了git日志中的addressesDenormalization以及新的数据库模式和合规的代码库:
突然,在开发过程中,收到了来自帮助台的一张工单,关于生产环境中的一个错误:“HALLO world”的打印不正确,它应该被更改为“Hello World!”。现在必须立即修复生产环境。Bob检出da1d744,创建了一个新的分支productionBugFixing,修复了代码并合并到master中准备部署到生产环境:
git checkout master
git checkout 472daa4
sh ./docker_start_env.sh
mvn package
mvn exec:java
图6显示了Bob在代码库中检出productionBugFixing,图7显示了Bob在生产环境中与数据库模式对齐的代码库。此外,由于ddl是版本化的,他可以本地复制数据库并以更安全的方式进行开发。
Alice:嘿,Bob,听说修复了,确信代码仍然与生产环境中的数据库模式兼容吗?不会有sql.exception被抛出,对吧?
Bob:就在推送之前,执行了指向生产数据库模式的集成测试,该模式由本地容器化的Postgres复制:
sh ./docker_start_env.sh
mvn test
Alice:好的!可以在生产环境中发布修复(图8)...
...可以继续在addressesDenormalization中工作(图9):
图9显示了Bob在addressesDenormalization中继续工作。
Alice:再次看到在合并到master时遇到了冲突,知道修复有一些影响。能再次测试master吗?
Bob:当然可以!
git checkout master
sh ./docker_start_env.sh
mvn test
亲爱的Alice,相信可以告诉dba运行新的增量*.sql,可以部署非规范化!
Alice:好的...很快会通知:-)
Bob的观点:通过容器化,可以轻松地设置开发环境,跳过数据库安装和配置等繁琐的细节。此外,可以本地访问和执行脚本,避免了通常来自共享开发环境的烦人问题。此外,由于*.sql脚本也是版本化的,对自动复制相关模式充满信心。