Oracle 兼容模式下的 H2 被验证为 H2,而非 Oracle。

3

我在生产环境中使用Oracle,所有的变更日志都是为Oracle编写的。而在我的开发环境中,我正试图在兼容Oracle模式下的H2实例上生成变更日志。这样可以提高集成测试的速度。

我的问题是Liquibase正在对我的变更日志进行H2验证,而不是Oracle验证。是否有一种方法可以强制Liquibase在db url看起来像H2的情况下执行Oracle验证?

我最大的问题是序列和dropNotNullConstraint验证。

Liquibase版本: 2.0.5(我也尝试了3.1.1,但问题依旧)

H2连接url: jdbc:h2:tcp://localhost:9092/test;MODE=Oracle;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1

我相信这是一个常见的场景,所以我想我可能做错了什么?

非常感谢您的帮助。


你是从代码还是从命令行调用Liquibase?如果是从代码中调用,那么你使用的是哪种语言? - yǝsʞǝla
我正在使用gradle-liquibase-plugin 链接,但我认为我可能会创建一个特定于我正在工作的项目的自定义gradle插件。 - james percy
1个回答

2

由于Liquibase是用Java实现的,并且依赖于JDBC,因此我将使用Java进行解释。 Liquibase有一个已实现的数据库列表。它取决于您从Java代码中如何调用它,但让我们假设您要么使用liquibase.database.DatabaseFactory,要么扩展它或实现类似的内容。通常,您的代码可能如下所示(Scala示例):

  def createLiquibase(dbConnection: Connection, diffFilePath: String): Liquibase = {
    val database = DatabaseFactory.getInstance.findCorrectDatabaseImplementation(new JdbcConnection(dbConnection))
    val classLoader = classOf[SchemaMigration].getClassLoader
    val resourceAccessor = new ClassLoaderResourceAccessor(classLoader)
    new Liquibase(diffFilePath, resourceAccessor, database)
  }

  def updateDb(db: DbConnectionProvider, diffFilePath: String): Unit = {
    val dbConnection = db.getConnection
    val liquibase = createLiquibase(dbConnection, diffFilePath)
    try {
      liquibase.update(null)
    } catch {
      case e: Throwable => throw e
    } finally {
      liquibase.forceReleaseLocks()
      dbConnection.rollback()
      dbConnection.close()
    }
  }

请注意这部分代码:DatabaseFactory.getInstance.findCorrectDatabaseImplementation(new JdbcConnection(dbConnection)),我们在其中传递了java.sql.Connection,Liquibase会为其找到适当的Database实现。您可以覆盖findCorrectDatabaseImplementation方法,甚至可以创建自己的Database子类。具体实现方式由您决定。 DatabaseFactory中的方法是public Database findCorrectDatabaseImplementation(DatabaseConnection connection) throws DatabaseException。从这里您可以了解更多关于Database类型的信息。您可以从H2或Oracle中继承它并覆盖某些部分。
如果您使用Liquibase cmd客户端,可以执行上述操作,构建一个jar文件等,然后从命令行运行,确保新类在类路径上。
H2的兼容模式不能保证完全支持Oracle、Postgres等数据库,因此在其上测试Oracle DML可能不是一个可靠的想法。它可能有效,但也有可能会出现问题。

1
我同意 H2 数据库未完全模拟 Oracle 数据库的风险,但是我们有一种 CI 构建方式,可以在 Oracle 数据库上进行测试,目的主要是缩短开发人员的周转时间。我会尝试重写“findCorrectDatabaseImplementation”方法,使用您提出的建议。 - james percy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接