Spring Boot中Flyway执行migrate时报schema不存在错误
Flyway创建
flyway_schema_history表时提示schema不存在问题排查 问题场景
已在首个Flyway迁移脚本中添加create schema if not exists testit authorization sa语句,但Flyway执行时仍报错找不到testit schema,无法创建历史记录表。
配置与日志信息
application-test.yml配置
spring: flyway: enabled: true create-schemas: true default-schema: testit driver-class-name: org.postgresql.Driver user: sa password: sa schemas: testit locations: filesystem:database/postgres/testit/testit tablespace: testit r2dbc: pool: initialSize: 1 maxSize: 2 maxIdleTime: 120000
错误日志
SQL State : 3F000 Error Code : 0 Message : ERROR: schema "testit" does not exist Position: 14 Location : () Line : 1 Statement : CREATE TABLE "testit"."flyway_schema_history" ( "installed_rank" INT NOT NULL, "version" VARCHAR(50), "description" VARCHAR(200) NOT NULL, "type" VARCHAR(20) NOT NULL, "script" VARCHAR(1000) NOT NULL, "checksum" INTEGER, "installed_by" VARCHAR(100) NOT NULL, "installed_on" TIMESTAMP NOT NULL DEFAULT now(), "execution_time" INTEGER NOT NULL, "success" BOOLEAN NOT NULL ) TABLESPACE "testit"
build.gradle依赖配置
核心依赖
Spring boot version - 2.7.11 Java version - 17 testImplementation('org.flywaydb:flyway-core') testImplementation('org.springframework:spring-jdbc:5.3.8') implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc' implementation 'org.postgresql:r2dbc-postgresql' implementation 'io.r2dbc:r2dbc-pool' runtimeOnly ('org.postgresql:postgresql')
TestContainers依赖
testContainerVersion = "1.18.3" testImplementation("org.testcontainers:testcontainers:$testContainerVersion") testImplementation("org.testcontainers:junitjupiter:$testContainerVersion") testImplementation("org.testcontainers:postgresql:$testContainerVersion") testImplementation("org.testcontainers:r2dbc:$testContainerVersion")
TestContainer配置类
@Testcontainers public class ContainersConfig { @Container static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:14.6")) .withDatabaseName("testit") .withUsername("sa") .withPassword("sa"); @AfterAll void stopContainer() { postgresContainer.stop(); } static { Startables.deepStart(postgresContainer).join(); } @DynamicPropertySource private static void setDatasourceProperties(DynamicPropertyRegistry registry) { registry.add("spring.r2dbc.url", () -> "r2dbc:postgresql://"+ postgresContainer.getHost() + ":" + postgresContainer.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT) + "/" + postgresContainer.getDatabaseName()); registry.add("spring.r2dbc.username", postgresContainer::getUsername); registry.add("spring.r2dbc.password", postgresContainer::getPassword); registry.add("spring.flyway.url", postgresContainer::getJdbcUrl); } }
排查思路与解决方案
核心原因
Flyway在执行迁移脚本之前,会优先尝试创建flyway_schema_history表来记录迁移状态。此时用户编写的迁移脚本尚未执行,testitschema还未被创建,因此触发报错。
虽然配置了create-schemas: true,但结合PostgreSQL特性,仍可能因以下原因失败:
- JDBC连接URL指向
testit数据库,但该数据库默认不存在testitschema(PostgreSQL默认schema为public); - 连接用户
sa缺乏创建schema的权限,导致create-schemas配置未生效。
解决方案
方案1:通过Flyway初始化SQL提前创建schema
在application-test.yml的Flyway配置中添加init-sql参数,让JDBC连接建立后立即执行schema创建语句:
spring: flyway: # 其他配置保持不变 init-sql: "CREATE SCHEMA IF NOT EXISTS testit AUTHORIZATION sa;"
该语句会在Flyway创建历史表之前执行,确保schema存在。
方案2:修改JDBC连接URL指定默认schema
将Flyway的JDBC连接URL修改为:
jdbc:postgresql://localhost:49165/testit?currentSchema=testit
保留create-schemas: true配置,Flyway会自动创建不存在的schema(需确保sa用户有权限)。
方案3:在TestContainer启动时提前创建schema
修改TestContainer的静态初始化逻辑,手动执行schema创建SQL:
static { Startables.deepStart(postgresContainer).join(); // 提前创建schema try (Connection conn = DriverManager.getConnection( postgresContainer.getJdbcUrl(), postgresContainer.getUsername(), postgresContainer.getPassword())) { try (Statement stmt = conn.createStatement()) { stmt.execute("CREATE SCHEMA IF NOT EXISTS testit AUTHORIZATION sa;"); } } catch (SQLException e) { throw new RuntimeException("Failed to create schema", e); } }
确保Flyway启动前,schema已存在。
额外注意事项
- 确认
sa用户拥有创建schema的权限,若为普通用户,需执行授权语句:GRANT CREATE SCHEMA ON DATABASE testit TO sa; - 检查迁移脚本命名符合Flyway规范(如
V1__create_schema.sql),确保Flyway能正确识别并执行首个脚本。
内容的提问来源于stack exchange,提问作者Sooraj V
相关产品推荐
相关产品推荐

