【问题标题】:H2 in Oracle compatibility mode is validated as H2, not oracleOracle 兼容模式下的 H2 被验证为 H2,而不是 oracle
【发布时间】:2014-02-20 13:38:31
【问题描述】:

在生产中,我使用的是 Oracle,并且我的所有变更日志都是在考虑 Oracle 的情况下编写的。 在我的开发环境中,我试图在 Oracle 兼容模式下在 H2 实例上生成更改日志。 这是为了提高集成测试速度。

我的问题是 Liquibase 正在针对 H2 而非 Oracle 验证我的变更日志。 即使我的 db url 看起来像 H2,是否有办法强制 Liquibase 针对 Oracle 进行验证?

我最头疼的是序列和 dropNotNullConstraint 验证。

Liquibase 版本: 2.0.5(我也试过 3.1.1,同样的问题)

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

我很确定这是一种常见情况,所以我想我可能做错了什么?

任何帮助将不胜感激

【问题讨论】:

  • 你是从代码还是从 cmd 调用 Liquibase?如果来自代码,那么您使用什么语言?
  • 我正在使用 gradle-liquibase-plugin link 但我想我可能只是针对我正在处理的项目创建自己的自定义 gradle 插件

标签: oracle gradle h2 liquibase


【解决方案1】:

由于 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 有点可疑。它可能会起作用,直到你发现它不起作用。

【讨论】:

  • 我同意 H2 不完全模仿 Oracle 的风险,但我们有一个 CI 构建,它也将针对 Oracle 数据库进行测试,其目的主要是减少开发人员的周转时间。我会尝试您关于覆盖 findCorrectDatabaseImplementation 方法的建议。
猜你喜欢
  • 2013-12-11
  • 1970-01-01
  • 2023-03-19
  • 2020-10-23
  • 2017-05-13
  • 2018-03-03
  • 2017-05-23
  • 2013-11-29
  • 2012-08-12
相关资源
最近更新 更多