如何使用 Oracle 数据库自动化源代码控制

How to automate source control with Oracle database

我在一个有数百个模式和多个开发人员的 Oracle 实例中工作。我们有一个开发实例,开发人员可以在测试或生产之前集成他们的工作。

我们希望对该集成开发数据库中的所有 DDL 运行 进行源代码控制。目前,这是通过产品 Red Gate 完成的,我们 运行 在对数据库进行更改后手动完成。 Redgate 发现模式中的内容与最后签入源代码管理的内容之间的更改,并制作差异脚本并将其放入源代码管理中。

然而,问题当然是 运行ning regdate 可能需要一些时间,而人们 运行 很少或根本不会进行小的更改。此外,redgate 一次只会查看一个模式,手动 运行 它针对所有模式以保证它们是最新的将非常耗时。但是,如果不能依赖源代码控制,它就会变得不那么有用...

拥有一些软件可以定期(甚至一天一次),或者当 DDL 被 运行 触发时,更新源代码管理(最好是 github因为这被其他团队使用)来自所有模式。

我似乎看不到任何可以简单地用于执行此操作的现有软件。

这样做有问题吗? (没有必要解决多个开发人员在同一天覆盖彼此的工作,因为我们在单独的流程中涵盖了这一点)有人这样做吗?谁能推荐一种方法来做到这一点?

在数据库版本控制 space 工作了 5 年(在 DBmaestro 担任产品管理总监)并且作为 DBA 工作了二十多年,我可以告诉你一个简单的事实您不能像对待 Java、C# 或其他文件那样对待数据库对象,并在简单的 DDL 脚本中保存更改。

原因有很多,我举几个:

  • 文件本地存储在开发人员的 PC 上,更改 s/he makes 不影响其他开发者。同样,开发商不 受到同事所做更改的影响。在数据库中这是 (通常)情况并非如此,开发人员共享同一个数据库 环境,因此提交给数据库的任何更改都会影响 其他。
  • 发布代码更改是使用签入/提交更改/ 等等(取决于您使用的源代码控制工具)。在那时候, 来自开发人员本地目录的代码被插入到 源代码控制存储库。想要获取最新的开发者 代码需要从源代码管理工具请求它。在数据库中 更改已经存在并影响其他数据,即使它不存在 签入存储库。
  • 文件签入期间,源代码管理工具执行冲突 检查同一个文件是否被另一个人修改和签入 在您修改本地副本期间的开发人员。又来了 在数据库中没有对此进行检查。如果你改变一个过程 您的本地 PC,同时我修改了相同的程序 从我的本地 PC 编写代码,然后我们覆盖彼此的更改。
  • 代码的构建过程是通过获取标签/latest来完成的 将代码版本复制到一个空目录,然后执行构建 – 编译。输出是二进制文件,我们在其中复制并替换 现存的。我们不在乎以前是什么。在数据库中我们不能 重新创建数据库,因为我们需要维护数据!还有 部署执行构建中生成的 SQL 个脚本 过程。
  • 执行 SQL 脚本时(使用 DDL、DCL、DML(对于静态 内容)命令)你假设当前的结构 创建脚本时环境与结构匹配。如果不, 那么当您尝试添加新列时,您的脚本可能会失败 已经存在。
  • 将 SQL 脚本视为代码并手动生成它们会导致 语法错误、数据库依赖错误、不正确的脚本 可重复使用,这使开发、维护、 测试那些脚本。此外,这些脚本可能 运行 与您认为的环境不同的环境 运行 上。
  • 有时版本控制库中的脚本不匹配 被测试的对象的结构然后错误将 在生产中发生!

还有很多,但我想你已经明白了。

我发现以下内容有效:

  1. 使用强制版本控制系统 check-out/check-in 对数据库对象的操作。这会 确保版本控制存储库与之前的代码匹配 在读取签入对象的元数据时签入 操作而不是作为一个单独的步骤手动完成。这也让 多个开发人员在同一个数据库上并行工作,同时 防止它们意外覆盖彼此的代码。
  2. 使用影响分析,将基线作为 比较以确定冲突并确定是否存在差异(当 比较源代码控制之间的对象结构 存储库和数据库)是一个真正的变化,起源于 发展或差异源于不同的路径和 那么应该跳过它,例如不同的分支或紧急情况 修复。
  3. 使用知道如何为许多人执行影响分析的解决方案 模式,使用 UI 或使用 API 以便最终 自动化构建和部署过程。

我写的一篇文章已发表here,欢迎阅读

我们借助 PL/SQL 函数、python 脚本和 shell 脚本来完成此操作:

  • PL/SQL函数可以生成整个schema的DDL并且returnsthis as CLOB
  • python 脚本连接到数据库,获取 DDL 并将其存储在文件中
  • shell 脚本 运行 添加修改的源代码管理(我们在这里使用 Bazaar)。

您可以在 PasteBin 上看到脚本:

shell脚本:

python schema_exporter.py
d=$(date +%Y-%m-%d__%H_%M_%S)
bzr add
bzr st | grep -q -E 'added|modified' &&  commit -m "Database objects on $d"
exit 0

此 shell 脚本每天从 cron 配置为 运行。

对我来说,您的工作方式似乎是倒退的:开发人员 运行 以无序的方式针对数据库进行 DDL,然后您需要一个自动化工具来推断 运行 的更改(和 DDL)运行.

如果您改为执行以下操作,流程将得到更好的控制:

在此工作流程中,数据库只能通过自动迁移脚本进行更改,不允许任何人手动进行更改。这对你有用吗?

(我为 Redgate 开发 Oracle 工具) 实际上,使用这些工具,您已经可以使用 Schema Compare for Oracle 来满足我的要求。

您可以在 UI 中或通过命令行比较多个模式 - 我认为您想要的是自动化命令行工具,它可以创建不同的脚本,在源和目标之间同步(实时、快照或脚本)并生成报告。

您可以自动将命令行同步到一个脚本文件夹,这是您的源代码签出,然后 运行 一个命令来提交更改。

我认为这一切都很好:)