65.9K
CodeProject 正在变化。 阅读更多。
Home

使用容器测试数据库架构演进

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2018 年 3 月 13 日

CPOL

6分钟阅读

viewsIcon

7321

downloadIcon

37

Dockerized Postgre 以改善版本化代码库和 DB 架构之间的耦合

引言

本文展示了开发经理Alice如何运用一些技术,向开发人员Bob提供保证,确保他编写的代码符合给定的数据库模式,即数据对象的字段也作为表中的列存在。这种方法基于集成测试、Postgres容器化、版本控制和数据库模式版本管理。读者可以将这些想法应用于其他技术,如WSDL版本管理或其他数据库引擎。

背景

我是Alice,在介绍我的方法之前,我先澄清一下我之前使用的一些关键词的含义。

首先,什么是集成测试?它是软件测试的一个阶段,其中两个或多个模块被组合在一起作为一个组进行测试。在这种情况下,我们希望测试我们的代码是否能够执行真实的数据库选择,即某个特定表中所有需要的列同时存在于模式和代码中。在一个更复杂的场景中,它会听起来像“我们希望测试我们的数据访问层是否能够对预生产环境中配置的当前数据源执行CRUD操作”。

其次,什么是模式版本管理?软件开发中的一项好习惯是严格地耦合代码和模式,因此,*.sql脚本也应该进行版本管理。在我的团队中,我们使用适当的名称对它们进行排序(例如:0_1 -> 0_2 -> 1_0 -> ...,可能使用某种语义版本控制约定),并将它们分为DML(数据操作语言)脚本和DDL(数据定义语言)脚本。其中一个主要的好处是,我们可以以编程方式在任何地方重现模式,例如在生产环境中、在持续集成管道的特定阶段,或者……在一个容器化的数据库中。:-)

第三,什么是容器化的Postgres?你可以将其视为一个运行在你的操作系统上的轻量级虚拟机,其中包含你的Postgres数据库。你可以启动、停止、访问、配置、分发它,更重要的是,你只需一次性、以编程方式、集中地完成这些操作!

Bob的开发机

我又回来了,我是Alice。在我的团队中,我们分发这种开发机的配置。正如你所见,它是相当通用的,伙计们仍然可以浏览Facebook或阅读一些网球文章。:-)

  • Ubuntu 16.04 LTS
  • jdk 1.8.0_111
  • docker 1.12.5
  • mvn 3.3.9
  • git 2.7.4

你好,我是Bob,一名软件工程师。我想谈谈我日常的开发活动。一旦我在IDE中打开了项目simple_db_reader,我就会编写一些代码。在提交之前,我遵循以下步骤:

  1. 我运行sh ./docker_start_env.sh来启动/重启我的本地Postgres。这很好,因为我不需要任何数据库安装,而且所有*.sql脚本都位于simple_db_reader/sql下,并按字母顺序自动执行。此外,我还可以用我的PgAdmin访问一些表!这对于在本地测试新脚本非常棒!
  2. 我通过执行mvn package来编译和测试我的代码。
  3. 我可以使用mvn exec:java运行jar包。
  4. 如果一切正常,我将提交到某个远程分支。

Alice办公室里繁忙的一天

Alice: 几天前,我们在生产环境中发布了第一个版本(变更集da1d744)。你可以通过以下命令查看它:

  1. git checkout master
  2. git checkout da1d744
  3. sh ./docker_start_env.sh
  4. mvn package
  5. mvn exec:java

图2图3显示了git日志中的da1d744检出以及代码与数据库模式之间的关系。

图 2

图 3

与此同时,DBA请求了一个数据库反范式化的变更请求,删除address表并向people表添加一个新的zipcode列。需要强调的是,这个请求对代码有很大的影响,所以我们需要修改集成测试AppTest.testDatabaseAccess,以确保代码库仍然与新模式保持一致。创建了一个新的分支addressesDenormalization,Bob正在上面工作。

  1. git checkout addressesDenormalization

图4图5显示了git日志中的addressesDenormalization以及带有匹配代码库的新数据库模式。

图 4

图 5

突然,在开发过程中,我们收到一个帮助台的工单,关于生产环境中的一个bug:“HALLO world”的打印不正确,需要更改为“Hello World! We have to hot fix production now”。Bob检出了da1d744,创建了一个新分支productionBugFixing,修复了代码,并将其合并到master分支,准备部署到生产环境。

  1. git checkout master
  2. git checkout 472daa4
  3. sh ./docker_start_env.sh
  4. mvn package
  5. mvn exec:java

通过检出productionBugFixing图6),Bob可以在一个与生产数据库模式匹配的代码库中工作(图7)。此外,由于DDL是版本化的,他可以本地复制数据库并更安全地进行开发。

图 6

图 7

Alice: 嘿Bob,我听说你修复了bug,你确定代码仍然符合生产环境中的数据库模式吗?不会出现sql.exception吧!?

Bob: 在提交之前,我执行了集成测试,指向由本地容器化Postgres复制的生产数据库模式。

  1. sh ./docker_start_env.sh
  2. mvn test

Alice: 没问题!我们可以发布这个修复到生产环境了(图8)...

图 8

...然后你可以继续处理addressesDenormalization图9)。

图 9

Bob: 对于这项活动,我检出了addressesDenormalization,添加了一些ddl脚本来执行反范式化,修复了损坏的数据层代码,并执行了我的测试。我已经准备好合并到master了(图10)。

图 10

Alice: 再次,我注意到你在合并到master时有冲突,而且我知道你的修复有一些影响。你能再次测试一下master吗?

Bob: 当然!

  1. git checkout master
  2. sh ./docker_start_env.sh
  3. mvn test

亲爱的Alice,我相信你可以告诉DBA运行新的增量*.sql脚本,我们就可以部署这个反范式化了!

Alice: 好的... 我很快会通知你:-)

关注点

Bob的观点:有了容器化,我可以轻松地设置我的开发环境,跳过所有痛苦的细节,比如数据库安装和配置。而且,我可以本地访问和执行脚本,避免了共享开发环境中通常会出现的烦人问题。此外,由于*.sql脚本也经过版本管理,我对自动复制相关模式很有信心。

Alice的观点:在构建开发环境的第一个阶段,我们配置了一次容器化的Postgres,并在团队之间共享。每个人都享受到了即时可用的安装,我们也使用了容器的克隆在我们的持续集成管道中。此外,保持数据库模式版本化的做法有一些优点:我们可以始终从头开始重建一个特定的快照,并与特定的代码库检出进行关联。这在不同环境参与发布生命周期时非常有用。而且,通过共享这些脚本,我们可以与DBA和其他同事进行正式沟通,避免危险的误解。最后,数据访问层与代码库之间的集成测试指向真实的数据库实例,让我们对JDBC驱动程序或某些表索引等技术细节有了一定程度的信心。

历史

  • 2018 年 3 月 13 日:初始版本
© . All rights reserved.