我在一个拥有数百个模式和多名开发人员的Oracle实例中工作。我们有一个开发实例,开发人员可以在测试或生产之前集成他们的工作。
我们希望在这个集成开发数据库中运行所有DDL的源代码管理。目前,这是通过产品Red Gate完成的,我们在更改数据库后手动运行该产品。Redgate发现模式中的内容和上次检查到源代码管理中的内容之间的变化,并编写差异脚本并将其放入源代码管理。
然而,问题当然是运行regdate可能需要一些时间,人们很少运行它,或者根本不运行它来进行小的更改。此外,redgate一次只查看一个模式,并且手动对所有模式运行它以确保它们是最新的,这将非常耗时。然而,如果源代码控制的代码不能被依赖,它就会变得不那么有用。。。
理想的情况似乎是拥有一些软件,这些软件可以定期(甚至一天一次),或者在DDL运行触发时,从所有模式更新源代码管理(最好是github,因为其他团队都在使用它)。
我似乎看不到任何现有的软件可以简单地用来做这件事。
这样做有问题吗?(没有必要解决多个开发人员在同一天覆盖彼此工作的问题,因为我们在单独的流程中已经涵盖了这一点)有人这样做吗?有人能推荐一种方法吗?
我们在PL/SQL函数、python脚本和shell脚本的帮助下完成这项工作:
- PL/SQL函数可以生成整个模式的DDL,并将其作为CLOB返回
- python脚本连接到数据库,获取DDL并将其存储在文件中
- shell脚本运行源代码管理来添加修改(我们在这里使用Bazaar)
你可以在PasteBin:上看到脚本
- PL/SQL函数如下:http://pastebin.com/AG2Fa9zL
- python程序(schema_exporter.py):http://pastebin.com/nd8Lf0gK
- shell脚本:
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运行。
在数据库版本控制领域工作了5年(作为DBmaestro的产品管理总监),并且已经做了20多年的DBA,我可以告诉您一个简单的事实,即您不能像处理Java、C#或其他文件那样处理数据库对象,并将更改保存在简单的DDL脚本中。
原因有很多,我将列举几个:
- 文件本地存储在开发人员的PC上,并且更改make不会影响其他开发人员。同样,开发人员不是受到同事改变的影响。在数据库中,这是(通常)不是这样,开发人员共享同一个数据库环境,因此提交给数据库的任何更改都会影响其他
- 发布代码更改是使用签入/提交更改完成的/等等(取决于您使用的源代码管理工具)。在这一点上,将来自开发人员本地目录的代码插入源代码管理存储库。想要获得最新信息的开发人员代码需要从源代码管理工具请求它。在数据库中更改已经存在并影响其他数据,即使它不是签入存储库
- 在文件签入期间,源代码管理工具执行冲突检查同一个文件是否被其他人修改和签入开发人员在您修改本地副本期间。再次出现数据库中没有对此进行检查。如果您从您的本地电脑,同时我用代码,然后我们覆盖彼此的更改
- 代码的构建过程是通过获取标签/最新版本的代码复制到一个空目录中,然后执行构建—编写输出是二进制文件,我们在其中复制&更换现有。我们不在乎以前发生了什么。在数据库中,我们不能重新创建数据库,因为我们需要维护数据!此外部署执行生成中生成的SQL脚本过程
- 当执行SQL脚本(带有DDL、DCL、DML(用于静态content)命令)环境与创建脚本时的结构匹配。如果不是,然后,当您尝试添加新列时,脚本可能会失败已存在
- 将SQL脚本视为代码并手动生成会导致语法错误、数据库依赖项错误、脚本可重复使用,测试那些脚本。此外,这些脚本可能在与您认为它将运行的环境不同的环境上
- 有时版本控制存储库中的脚本不匹配测试对象的结构,然后出现错误在生产中发生
还有很多,但我想你已经明白了。
我发现有效的方法如下:
- 使用强制执行的版本控制系统对数据库对象的签出/签入操作。这将确保版本控制存储库与在读取签入中对象的元数据时签入操作,而不是作为一个单独的步骤手动完成。这也允许几个开发人员在同一个数据库上并行工作,同时防止它们意外地覆盖彼此的代码
- 使用影响分析,将基线作为比较以识别冲突并确定差异(当比较源代码管理之间的对象结构存储库和数据库)是一个真正的变化来自不同道路的发展或差异,以及则应该跳过它,例如不同的分支或紧急情况修复
- 使用一个知道如何对许多人执行影响分析的解决方案架构,使用UI或使用API,以便最终自动化构建&部署过程
我写的一篇关于这方面的文章已经发表在这里,欢迎您阅读。
对我来说,您的工作方式似乎是向后的:开发人员以无序的方式对DB运行DDL,然后您需要一个自动工具来推断运行的更改(和DDL)。
如果你采取以下措施,这个过程会得到更好的控制:
- 开发人员将DDL编写为SQL脚本,最好使用像Flyway这样的迁移工具(http://flywaydb.org/documentation/migration/sql.html)
- 迁移脚本已检入版本控制
- 迁移脚本定期针对数据库运行(例如通过迁移工具)
在这个工作流程中,数据库只能通过自动迁移脚本进行更改,任何人都不允许手动进行更改。这对你有用吗?
(我为Redgate开发Oracle工具)实际上,使用这些工具,您已经可以满足我认为您使用Schema Compare for Oracle的要求。
您可以在UI中或通过命令行比较多个模式——我认为您所追求的是自动化命令行工具,该工具可以创建差异脚本,在源和目标(实时、快照或脚本)之间同步,并生成报告。
您可以自动执行命令行以同步到作为源代码签出的脚本文件夹,然后运行命令提交更改。
我认为这一切都很好:)
我们构建了一个商业工具,将Oracle与Git连接起来。它可以帮助您使用Git管理数据库对象。基本上,数据库成为开发人员的工作目录。您可以在数据库中执行git操作,如重置、提交、分支、合并等。数据库代码会自动更新。也许值得一看:https://www.gitora.com