Flyway: как создать базу данных SQL Server перед созданием flyway_schema_history

avatar
Feng Lei
9 августа 2021 в 06:02
459
1
0

Наш проект использует AWS CloudFormation для настройки экземпляра SQL Server, а затем использует Flyway для переноса таблиц. Поскольку база данных еще не создана (AWS не может создать базу данных одновременно с созданием экземпляра SQL Server), Flyway затем создает flyway_schema_history в базе данных по умолчанию [master], что приводит к сбою разрешения:

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)

В этом случае мы предоставляем URL-адрес JDBC Flyway, но без указания базы данных, просто подключаемся к экземпляру (например, jdbc:sqlserver://db.tracking.sandbox.aws.xxx.com:1433).

Данное AWS CloudFormation не позволяет нам создавать базу данных одновременно с созданием экземпляра SQL Server. Если есть способ со стороны Flyway, можно создать базу данных до того, как flyway создаст flyway_schema_history, таким образом, Flyway позже создаст flyway_schema_history во вновь созданной базе данных.

Есть ли у вас какие-либо идеи для достижения этого?

Источник

Ответы (1)

avatar
Mark Bramnik
9 августа 2021 в 08:05
2

Я не пробовал сам (сейчас передо мной нет установки), но рассмотрите два способа:

  1. Создать БД отдельно от пролетного пути перед ее запуском. Например, если вы запускаете flyway как шаг в сценарии, запустите другой сценарий перед этим шагом.
  2. Если вы хотите создавать базы данных внутри пролетного пути, рассмотрите возможность использования обратных вызовов пролетного пути — это перехватчики для различных этапов жизненного цикла пролетного пути:

В частности, beforeMigrate может выполнить эту работу.

Обратите внимание, что вы можете реализовать обратный вызов как в коде SQL, так и в коде Java для большей гибкости

Feng Lei
10 августа 2021 в 04:29
0

Ага. Я пробовал ваш второй вариант, но безуспешно. Я выберу первый вариант, который использует JDBC для создания БД (конечно, он будет работать без сомнений).