如何在Flyway中进行部分迁移以进行测试?

huangapple go评论71阅读模式
英文:

How to do partial migration in Flyway for testing?

问题

我正试图编写一个测试来验证我的新迁移脚本(位于 src/main/resources/db/migration)是否在我的 Postgres 数据库中的现有数据上正确执行。

我有 5 个迁移脚本,其中第二个脚本创建了带有某些列的初始 "Users" 表,第五个脚本在该现有 "Users" 表中添加了一个新列,并为该新列设置了默认值。

首先,我想仅迁移到该脚本,以便获得 "Users" 表的初始版本,然后我将正常填充它,最后,通过运行第 5 个脚本完成迁移,然后检查第 5 个脚本是否实际更新了现有数据。

但是,我不太明白如何仅迁移到某个版本,然后稍后再迁移到其余版本...

以下是我目前的进展:

实际测试

@RunWith(SpringRunner.class)
@SpringBootTest
class MigrationTest extends ComponentTest {

  private static final String USER_ID = "1337";

  @Autowired
  private InitialUserRepository initialUserRepository;
  @Autowired
  private UserRepository userRepository;

  @Autowired
  private Flyway flyway;

  @Transactional
  @Test
  public void test() {

    flyway.baseline(); // 默认为 1
    flyway.migrate(); // 这将迁移到最终的脚本/版本,其中将添加新列
    // 用只迁移到版本 2 的部分迁移替换上述行 flyway.migrate()
    
    var initialUserMappingEntity = new InitialUserMappingEntity(USER_ID, "一些其他数据");
    initialUserRepository.saveAndFlush(initialUserMappingEntity);

    var user = initialUserRepository.findById(USER_ID);
    assertTrue(user.isPresent());

    // 在此处完成完整的迁移,类似于 flyway.migrate(5)

    var updatedUser = userRepository.findById(USER_ID);
    assertTrue(updatedUser.isPresent());
    assertNotNull(updatedUser.get().getNewColumn());
  }
}

EmptyMigrationStrategyConfig

@Configuration
public class EmptyMigrationStrategyConfig {

  @Bean
  public FlywayMigrationStrategy flywayMigrationStrategy() {
    return flyway -> {
      // 什么也不做
    };
  }
}

application-test.yaml

spring:
  flyway:
    locations: classpath:/db/migration
英文:

I am trying to write a test to validate whether my new migration script (located in src/main/resources/db/migration) executes correctly on the existing data in my Postgres DB.

I have 5 migration scripts where the 2nd one creates the initial Users table with some columns and the 5th one adds onto that existing Users table with a new column and default values for that new column.

First, I would like to only migrate up to the script, so that the initial version of Users table, then I will populate it normally, and finally, complete the migration by running the 5th script, and then check if the 5th script actually updated the existing data or not. However, I do not understand exactly how I can just migrate only to some version, and then later on migrate to the remaining versions...

Here is what I have so far:

Actual Test

@RunWith(SpringRunner.class)
@SpringBootTest
class MigrationTest extends ComponentTest {

  private static final String USER_ID = "1337";

  @Autowired
  private InitialUserRepository initialUserRepository;
  @Autowired
  private UserRepository userRepository;

  @Autowired
  private Flyway flyway;

  @Transactional
  @Test
  public void test() {

    flyway.baseline(); // default 1
    flyway.migrate(); // this will migrate to the final script/version where it will add the new column
    // replace the above line, flyway.migrate(), with a partial migration to version 2 ONLY, something like flyway.migrate(2)

    var initialUserMappingEntity = new InitialUserMappingEntity(USER_ID, "some other data");
    initialUserRepository.saveAndFlush(initialUserMappingEntity);

    var user = initialUserRepository.findById(USER_ID);
    assertTrue(user.isPresent());

    // complete the full migration here, something like flyway.migrate(5)

    var updatedUser = userRepository.findById(USER_ID);
    assertTrue(updatedUser.isPresent());
    assertNotNull(updatedUser.get().getNewColumn());
  }
}

EmptyMigrationStrategyConfig

@Configuration
public class EmptyMigrationStrategyConfig {

  @Bean
  public FlywayMigrationStrategy flywayMigrationStrategy() {
    return flyway -> {
      // do nothing
    };
  }
}

application-test.yaml

spring:
  flyway:
    locations: classpath:/db/migration

答案1

得分: 0

你正在寻找 flyway.target 选项(API 中的 .target())。详见 https://flywaydb.org/documentation/commandline/migrate#target

这个配置参数用于设置要迁移到的版本。因此,如果你有 3 个迁移 V1__、v2__、v3__,使用 flyway.target=2 可以只迁移 V1__v2__

英文:

You are looking for the flyway.target option (.target() in the api). See https://flywaydb.org/documentation/commandline/migrate#target.

This config parameter sets the version to migrate to. So if you have 3 migrations V1__, v2__, v3__ use flyway.target=2 to migrate just V1__ and v2__.

答案2

得分: 0

最终,我将以下代码段进行了替换:

var initialUserMappingEntity = new InitialUserMappingEntity(USER_ID, "some other data");
initialUserRepository.saveAndFlush(initialUserMappingEntity);

用位于 /db/testdata/V2.1__insert_user_data.sql 的插入脚本,然后执行一次迁移直至结束。

所以基本上你需要在最终要测试的 /db/migration 脚本之前添加一个插入脚本,并修改你的 spring.flyway.locations 来包含这两个基本路径。

英文:

In the end I replaced the

var initialUserMappingEntity = new InitialUserMappingEntity(USER_ID, "some other data");
initialUserRepository.saveAndFlush(initialUserMappingEntity);

with an insertion script located in: /db/testdata/V2.1__insert_user_data.sql
and then just did one migration until the end.

So you basically need to add an insertion script that comes before the final script that you want to test in your /db/migration and then modify your spring.flyway.locations to have these two base path

答案3

得分: 0

在你的Spring Boot测试中,你可以添加属性 flyway.target

@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    properties = {"spring.flyway.clean-disabled=false", "spring.flyway.target=2"}
)
class MyTest {...}

这将在此测试的目的下,执行所有版本直到和包括版本2的所有迁移,忽略后续的迁移。

英文:

In your Spring boot test, you could add property flyway.target

@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    properties = {"spring.flyway.clean-disabled=false", "spring.flyway.target=2"}
)
class MyTest {...}

This would, for the purpose of this test, execute all migrations until and including version 2, ignoring later ones.

huangapple
  • 本文由 发表于 2020年8月31日 20:24:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63670781.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定