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

Posted

技术标签:

【中文标题】Flyway:如何在 flyway 创建 flyway_schema_history 之前创建 SQL Server 数据库【英文标题】:Flyway: How to create a SQL Server database before flyway creating the flyway_schema_history 【发布时间】:2021-10-12 21:00:13 【问题描述】:

我们的项目使用 AWS CloudFormation 设置 SQL Server 实例,然后使用 Flyway 应用表迁移。由于尚未创建数据库(AWS无法在创建SQL Server实例的同时创建数据库),Flyway随后在默认数据库[master]下创建flyway_schema_history导致权限失败:

org.flywaydb.core.internal.sqlscript.FlywaySqlScriptException: Migration  failed
-----------------
SQL State  : S0001
Error Code : 262
Message    : CREATE TABLE permission denied in database 'master'.
Location   :  ()
Line       : 1
Statement  : CREATE TABLE [master].[guest].[flyway_schema_history] (
    [installed_rank] INT NOT NULL,
    [version] NVARCHAR(50),
    [description] NVARCHAR(200),
    [type] NVARCHAR(20) NOT NULL,
    [script] NVARCHAR(1000) NOT NULL,
    [checksum] INT,
    [installed_by] NVARCHAR(100) NOT NULL,
    [installed_on] DATETIME NOT NULL DEFAULT GETDATE(),
    [execution_time] INT NOT NULL,
    [success] BIT NOT NULL
);
ALTER TABLE [master].[guest].[flyway_schema_history] ADD CONSTRAINT [flyway_schema_history_pk] PRIMARY KEY ([installed_rank]);
CREATE INDEX [flyway_schema_history_s_idx] ON [master].[guest].[flyway_schema_history] ([success]);

    at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.handleException(DefaultSqlScriptExecutor.java:277)
    at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.executeStatement(DefaultSqlScriptExecutor.java:224)
    at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.execute(DefaultSqlScriptExecutor.java:128)
    at org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory$1$1.call(JdbcTableSchemaHistory.java:115)
    at org.flywaydb.core.internal.jdbc.TransactionalExecutionTemplate.execute(TransactionalExecutionTemplate.java:66)
    at org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory$1.call(JdbcTableSchemaHistory.java:111)
    at org.flywaydb.core.internal.database.sqlserver.SQLServerApplicationLockTemplate.execute(SQLServerApplicationLockTemplate.java:62)
    at org.flywaydb.core.internal.database.sqlserver.SQLServerConnection.lock(SQLServerConnection.java:96)
    at org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory.create(JdbcTableSchemaHistory.java:101)
    at org.flywaydb.core.Flyway$1.execute(Flyway.java:217)
    at org.flywaydb.core.Flyway$1.execute(Flyway.java:172)
    at org.flywaydb.core.Flyway.execute(Flyway.java:588)
    at org.flywaydb.core.Flyway.migrate(Flyway.java:172)

在这种情况下,我们提供 Flyway JDBC URL,但不指定数据库,只需连接到实例(即 jdbc:sqlserver://db.tracking.sandbox.aws.xxx.com:1433)。

鉴于 AWS CloudFormation 不允许我们在创建 SQL Server 实例的同时创建数据库。如果 Flyway 端有办法可以在 Flyway 创建 flyway_schema_history 之前创建数据库,那么 Flyway 后面会在新创建的数据库下创建 flyway_schema_history。

你有什么想法可以实现吗?

【问题讨论】:

【参考方案1】:

我自己没有尝试过(目前没有摆在我面前的设置),但考虑两种方法:

    在运行之前与 flyway 分开创建 DB。例如,如果您将 flyway 作为脚本中的一个步骤运行,请在此步骤之前运行另一个脚本。 如果您想使用 flyway 在内部创建数据库,请考虑使用 Flyway 回调 - 这些是 flyway 生命周期中各个步骤的挂钩:

更具体地说,beforeMigrate 可能会完成这项工作。

请注意,您可以在 SQL 和 Java 代码中实现回调以获得更大的灵活性

【讨论】:

是的。我试过你的第二种选择,但没有任何运气。我将采用第一个使用 JDBC 来创建数据库的选项(当然,毫无疑问它会起作用)。

以上是关于Flyway:如何在 flyway 创建 flyway_schema_history 之前创建 SQL Server 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 flyway 创建全文目录?

如何创建具有快照隔离级别的 Flyway 模式历史记录?

如何使用flyway创建数据库?

如何在flyway创建的postgresql jdbc连接上设置时区?

如何创建脚本或 Flyway 可以配置为每次使用 SQL 回调调用它?

如何在 Flyway 中设置排序规则?