Flyway:如何在 flyway 创建 flyway_schema_history 之前创建 SQL 服务器数据库
Flyway: How to create a SQL Server database before flyway creating the flyway_schema_history
我们的项目使用 AWS CloudFormation 设置 SQL 服务器实例,然后使用 Flyway 应用 table 迁移。因为数据库还没有创建(AWS在创建SQL服务器实例时不能同时创建数据库),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.call(JdbcTableSchemaHistory.java:115)
at org.flywaydb.core.internal.jdbc.TransactionalExecutionTemplate.execute(TransactionalExecutionTemplate.java:66)
at org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory.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.execute(Flyway.java:217)
at org.flywaydb.core.Flyway.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 服务器实例的同时创建数据库。如果Flyway这边有办法可以在flyway创建flyway_schema_history之前先创建一个数据库,这样Flyway后面会在新创建的数据库下创建flyway_schema_history
你有什么想法可以实现吗?
我还没有自己尝试过(现在我面前没有设置),但可以考虑两种方式:
- 在 运行s 之前,与 flyway 分开创建 DB。例如,如果您将 运行ning flyway 作为脚本中的一个步骤,运行 在此步骤之前的另一个脚本。
- 如果您想在飞路内部创建数据库,请考虑使用飞路回调——这些是飞路生命周期中各个步骤的挂钩:
更具体地说,beforeMigrate 可以胜任。
请注意,您可以在 SQL 和 Java 代码中实现回调以获得更大的灵活性
我们的项目使用 AWS CloudFormation 设置 SQL 服务器实例,然后使用 Flyway 应用 table 迁移。因为数据库还没有创建(AWS在创建SQL服务器实例时不能同时创建数据库),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.call(JdbcTableSchemaHistory.java:115)
at org.flywaydb.core.internal.jdbc.TransactionalExecutionTemplate.execute(TransactionalExecutionTemplate.java:66)
at org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory.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.execute(Flyway.java:217)
at org.flywaydb.core.Flyway.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 服务器实例的同时创建数据库。如果Flyway这边有办法可以在flyway创建flyway_schema_history之前先创建一个数据库,这样Flyway后面会在新创建的数据库下创建flyway_schema_history
你有什么想法可以实现吗?
我还没有自己尝试过(现在我面前没有设置),但可以考虑两种方式:
- 在 运行s 之前,与 flyway 分开创建 DB。例如,如果您将 运行ning flyway 作为脚本中的一个步骤,运行 在此步骤之前的另一个脚本。
- 如果您想在飞路内部创建数据库,请考虑使用飞路回调——这些是飞路生命周期中各个步骤的挂钩:
更具体地说,beforeMigrate 可以胜任。
请注意,您可以在 SQL 和 Java 代码中实现回调以获得更大的灵活性