Flyway: How to create a SQL Server database before flyway creating the flyway_schema_history

5kgi1eie  于 2023-02-28  发布在  SQL Server
关注(0)|答案(2)|浏览(157)

Our project uses AWS CloudFormation to set up a SQL Server instance and then uses Flyway to apply table migrations. Because the database is not yet created(AWS can't create a database at the same time when creating an SQL Server instance), Flyway then creates the flyway_schema_history under the default database [master] which result in a permission failure:

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)

In this case, we provide Flyway JDBC URL but without specifying a database, just connect to an instance (i.e jdbc:sqlserver://db.tracking.sandbox.aws.xxx.com:1433).

Given AWS CloudFormation doesn't allow us to create a database at the same time while creating the SQL Server instance. If there is a way from the Flyway side can create a database before the flyway creating the flyway_schema_history, thus Flyway later will create the flyway_schema_history under the newly created database.

Do you have any idea to achieve that?

qkf9rpyu

qkf9rpyu1#

I haven't tried by myself (don't have a setup in front of me right now), but consider two ways:

  1. Create DB separately from flyway, before it runs. For example, if you're running flyway as a step in the script, run another script prior to this step.
  2. If you want to create databases internally with the flyway, consider using Flyway Callbacks - these are hooks for various steps in the lifecycle of the flyway:

More specifically beforeMigrate might do the job.

Note that you can implement the callback in both SQL and Java code for more flexibility

mtb9vblg

mtb9vblg2#

All flyway callbacks except beforeConnect require a connection to a database to work, so if you want to create the database, I'd give beforeConnect a go.

相关问题