Flyway 迁移在 MS SQL Server 中成功,但在 H2 数据库中失败

Posted

技术标签:

【中文标题】Flyway 迁移在 MS SQL Server 中成功,但在 H2 数据库中失败【英文标题】:Flyway migration succeeds in MS SQL Server but fails in H2 database 【发布时间】:2017-09-25 09:39:36 【问题描述】:

我的应用程序中的数据库方案由Flyway 迁移管理。这些迁移是为 MS SQL Server 设计的,并且已经执行了很多次,没有任何问题。

我决定在运行测试之前重用迁移来设置测试数据库 (H2)。并为此在 Spring 上下文中创建了以下 bean:

@Bean
public DataSource dataSource() 
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("org.h2.Driver");
    // Scheme = test_db, Compatibility mode = MSSQLServer
    dataSource.setUrl("jdbc:h2:mem:test_db;MODE=MSSQLServer;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;" +
            "INIT=CREATE SCHEMA IF NOT EXISTS test_db\\;SET SCHEMA test_db");
    dataSource.setUsername("sa");
    dataSource.setPassword("");

    return dataSource;


@Bean
public Flyway flyway() 
    Flyway flyway = new Flyway();
    flyway.setDataSource(dataSource());
    flyway.setSchemas("test_db");
    flyway.setLocations("filesystem:db\\migration");
    flyway.migrate();  // Exception is thrown from here !!!
    return flyway;

但在 Spring 上下文初始化期间,我收到以下异常,说明迁移脚本的第一行出现语法错误:

org.flywaydb.core.internal.dbsupport.FlywaySqlScriptException: Migration V1__init.sql failed

SQL State  : 42001
Error Code : 42001
Message    : Syntax error in SQL statement "SET XACT_ABORT[*] ON
...

显然有一些Flyway / MS SQL Server 脚本/H2 之间的兼容性问题,如果我从迁移脚本中删除SET XACT_ABORT[*] ON 行,它会给我另一个错误。

我是使用内存数据库的新手,我希望保持 Flyway 迁移不变。其他可能的解决方案是什么?

【问题讨论】:

我怕一个庞大的MS SQL Server和一个小的嵌入式数据库不能100%兼容。在可能的情况下,H2 支持 ANSI SQL 标准,并尝试与其他数据库兼容。不过还是有区别的。 (source) 【参考方案1】:

这是一个数据库生成的错误,不是 Flyway 错误。您使用的两个 DBMS 不完全兼容:MS SQL Server 接受的某些数据类型、函数等在 H2 中不可用,SQL 语法不完全相同等等。生成错误的语句特定于 MS SQL Server(请参阅docs)

我不知道 Flyway 会以何种方式自动翻译您使用的 DML 脚本。您必须自己创建内存模式。除非有人知道任何自动执行此操作的工具。

告诉我们你的持久层,你使用什么框架?

如果您正在测试 JPA Hibernate 应用程序,那么您可以在运行时启用模式的自动生成(通过在您的测试应用程序上下文使用的 persistence.xml 中设置 hibernate.hbm2ddl.auto 属性)。当然,您仍然需要用数据填充您的架构。您的脚本可能会为此工作。对此的手动解决方案可能是,在任何测试开始之前,打开与主数据库的第二个数据库连接,在域对象中选择您需要的数据,然后通过内存数据库连接将它们持久化。我没有尝试过,只是一个想法......

【讨论】:

谢谢!我将使用 Hibernate 生成 H2 架构(尽管与 MS SQL Server 中使用的实际架构会有一些差异),然后使用 DbUnit 填充它。

以上是关于Flyway 迁移在 MS SQL Server 中成功,但在 H2 数据库中失败的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 sql-server 上迁移时 Flyway 挂起

如何在 SQL Server 上的 Flyway 中禁用单个迁移的事务

如何在多架构 MS SQL Server 环境中使用 Flyway?

Flyway:如何在 flyway 创建 flyway_schema_history 之前创建 SQL Server 数据库

具有 SQL Server 集成安全性的 Flyway

flyway迁移后运行data.sql文件