【问题标题】:Create a unit test two check if two psql schema are the same创建一个单元测试两个检查两个 psql 模式是否相同
【发布时间】:2016-07-10 10:55:24
【问题描述】:

我的这个项目有一个庞大的数据库架构,有时会更新。

所以我有一个名为 schema.sql 的文件,其中包含当前架构,以及一个包含我随时间部署的所有补丁的目录(称为 patches/20160710.sql,具有第一个架构的文件称为 origin.sql) .

如果我进行全新安装,我会使用schema.sql,否则我会在更新时应用补丁。

我有一个测试服务器,在更新生产中的架构之前我会在其中进行测试,并且我已经自动化了几乎所有的事情。到目前为止效果很好。

不幸的是,一旦我写了一个不同的东西去schema.sql 和补丁。我的单元测试只针对一个新的数据库运行,所以测试没有失败,我发现错误只是我在测试服务器上尝试的补丁。

我想编写一个采用schema.sql 的单元测试,部署它,并将架构与应用在origin.sql 上的所有补丁生成的架构进行比较。

我还需要检查一些表是否具有相同的值。

数据库是postgresql,软件是node.js。

测试由 Gitlab CI 使用自定义 docker 映像运行,所以我真的可以用任何更好的语言进行测试。

当然,补丁和schema.sql 的数据库名称相同,所以我想我必须申请schema.sql,以某种方式转储它,然后删除数据库并从补丁重新创建它,再次转储并比较结果。

这种方法是否有意义或有更好的方法来实现我正在做的事情?

如果这有意义,那么转储两个数据库并比较它们的好方法是什么?

【问题讨论】:

  • Linux 命令行 pg_dump <connection params 1> --schema=<schema to compare> --schema-only > foo1.sql && pg_dump <connection params 2> --schema=<schema to compare> --schema-only > foo2.sql && diff foo1.sql foo2.sql。如果输出为空,则方案相同。比较数据几乎相同:psql <connection params 1> -c "<query>" > data1.txt && psql <connection params 2> -c "<query>" > data2.txt && diff data1.txt data2.txt.
  • @Abelisto 感谢您的提示。两个模式具有相同名称的事实呢?编写一个更改测试环境中第二个模式名称的 bash 脚本是一种好习惯吗?
  • 正如你所说,这只是一个提示。如何使用它取决于您。无论如何,我相信您几乎可以使用 bash 和 PostgreSQL 命令行工具来做任何事情。
  • @Abelisto 非常感谢您的提示,我创建了一个可以工作的丑陋脚本 - 我发布了答案,请随时改进它:)
  • 我绝对不是 bash-guru :o) 看着你的回答,你比我更有经验。比方说:我们应该记住并思考我们拥有的整套工具。祝你好运。

标签: node.js database postgresql unit-testing


【解决方案1】:

感谢Abelisto的提示我做了一个类似这个的脚本(我的bash-fu不太好,请随时改进):

#!/bin/bash
ORIGINAL_DB="tmp1"
INCREMENTAL_DB="tmp2"
SCHEMA="schema"

function clean_up {
  sudo -u postgres dropdb ORIGINAL_DB
  sudo -u postgres dropdb INCREMENTAL_DB
  sudo -u postgres createdb ORIGINAL_DB
  sudo -u postgres createdb INCREMENTAL_DB
}

function import_schemas {
  sudo -u postgres psql ORIGINAL_DB < database/sql/schema.sql

  for f in database/sql/patches/*.sql ; do
    [[ -f "$f" ]] || continue
    sudo -u postgres psql INCREMENTAL_DB < $f
  done
}

function compare_schemas {
  sudo -u postgres pg_dump ORIGINAL_DB --schema=SCHEMA --schema-only > foo1.sql
  sudo -u postgres pg_dump INCREMENTAL_DB --schema=SCHEMA --schema-only > foo2.sql
  line_diff=$(diff foo1.sql foo2.sql | egrep '^<|>' | wc -l)

  if [ $line_diff -ne 0 ]
  then
    diff foo1.sql foo2.sql
    exit -1
  fi
}

function compare_values {
  sudo -u postgres psql ORIGINAL_DB -c "SELECT * FROM roles_permissions ORDER BY idrole, idpermission;" > data1.txt
  sudo -u postgres psql INCREMENTAL_DB -c "SELECT * FROM roles_permissions ORDER BY idrole, idpermission;" > data2.txt

  line_diff=$(diff data1.txt data2.txt | egrep '^<|>' | wc -l)

  if [ $line_diff -ne 0 ]
  then
    exit -1
  fi
}

clean_up
import_schemas
compare_schemas
compare_values

exit 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 2019-11-25
    • 2012-11-16
    • 1970-01-01
    相关资源
    最近更新 更多