Spring Boot FlywayException:无法连接到数据库。配置url、用户和密码

Posted

技术标签:

【中文标题】Spring Boot FlywayException:无法连接到数据库。配置url、用户和密码【英文标题】:Spring Boot FlywayException: Unable to connect to the database. Configure the url, user and password 【发布时间】:2021-01-19 08:01:16 【问题描述】:

当我运行maven flyway:migrate 时,我得到了错误

未能执行目标 org.flywaydb:flyway-maven-plugin:6.5.5:migrate 项目 myProject 上的(默认 cli): org.flywaydb.core.api.FlywayException:无法连接到 数据库。配置url、用户和密码!

我的 application.yml 文件中有我的 Spring Boot 设置,但我猜这个错误意味着它没有检测到数据库配置。 This documention 说,“Spring Boot 将自动将 Flyway 与其 DataSource 自动连接,并在启动时调用它。”如果我在 flyway 插件部分将配置添加到我的 pom.xml 中,它会成功连接到数据库,但我希望它使用我的 application.yml 配置。不是 pom.xml。那我做错了什么?

有问题的回购链接:https://github.com/jack-cole/BrokenSpringBoot

application.yml

spring:
    datasource:
        driverClassName: org.postgresql.Driver
        url: "jdbc:postgresql://localhost:5433/myDB"
        username: postgres
        password: test123

依赖关系:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.16</version>
</dependency>
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>7.0.0</version>
</dependency>

插件:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>6.5.5</version>
</plugin>

【问题讨论】:

您是否尝试过实现flyway-core依赖? mvnrepository.com/artifact/org.flywaydb/flyway-core/7.0.0 是的,我已经有了。我只是忘了把它写在我的问题中。 【参考方案1】:

使用 maven 运行:

未能执行目标 org.flywaydb:flyway-maven-plugin:6.5.5:migrate 项目 myProject 上的(默认 cli): org.flywaydb.core.api.FlywayException:无法连接到 数据库。 配置网址、用户名和密码!

您可以在flyway-maven-plugin配置中配置url、用户和密码见First Steps Maven

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>7.0.0</version>
    <configuration>
        <url>jdbc:postgresql://localhost:5433/myDB</url>
        <user>postgres</user>
        <password>test123</password>
    </configuration>
</plugin>

或使用环境变量:

mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5433/myDB -Dflyway.user=postgres -Dflyway.password=test123

https://www.baeldung.com/database-migrations-with-flyway中的更多方法

使用 spring-boot 运行:

Spring Boot 在应用程序中自动配置和触发 Flyway 将 Flyway 核心库包含到项目中时启动。看 @ConditionalOnClass(Flyway.class) 的用法 FlywayAutoConfiguration:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Flyway.class)
@Conditional(FlywayDataSourceCondition.class)
@ConditionalOnProperty(prefix = "spring.flyway", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter( DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
      HibernateJpaAutoConfiguration.class )
@Import( FlywayEntityManagerFactoryDependsOnPostProcessor.class, FlywayJdbcOperationsDependsOnPostProcessor.class,
      FlywayNamedParameterJdbcOperationsDependencyConfiguration.class )
public class FlywayAutoConfiguration 
    ...

使用mvn spring-boot:runjava -jar app.jar 运行应用程序

注意:还要检查迁移脚本是否位于 db/migration 中,否则请提供具有 spring.flyway.locations 属性的位置

资源:

https://flywaydb.org/documentation/configuration/parameters/

https://flywaydb.org/documentation/getstarted/firststeps/maven/

https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-execute-flyway-database-migrations-on-startup

【讨论】:

这在部署 jar 时不起作用,这就是为什么我需要它来使用 application.yml 文件。 嗯,好的。我现在看到了你想要达到的目标。我编辑了我的答案。您还必须将迁移脚本放在 db/migration 目录中,或者如果它不同,请提供带有 spring.flyway.locations 属性的位置 如果我将配置放在 pom.xml 中,我可以很好地运行 flyway,但它不会在启动时运行 mvn spring-boot:run。我在FlywayAutoConfiguration 中的所有方法中都设置了断点,以查看是否可以收集任何内容,但它没有在其中任何一个上暂停。 尝试删除 pom.xml 中的 postgresql 和 flyway 版本,让 spring-boot 选择版本 这似乎不起作用。我在这里上传了 repo:github.com/jack-cole/BrokenSpringBoot【参考方案2】:

您引用了 Spring Boot 文档的一部分,但您不是通过 Spring Boot 启动迁移,而是作为 maven 任务启动的。

Flyway maven 插件不知道 spring boot 配置,它只考虑以下来源:Overriding order

    系统属性 环境变量 自定义配置文件 Maven 属性 插件配置部分 来自 settings.xml 的凭据 /flyway.conf Flyway Maven 插件默认值

在我的 PC 上,我使用了环境变量方法 - 我为构建插件和 Spring Boot 定义了相同的环境变量。

【讨论】:

如何通过 spring boot 启动 flyway? 这在您发布的链接中得到了准确的描述:flywaydb.org/documentation/plugins/springboot。在 application.properties 中定义 flyway-core 依赖项和 DataSource 后,任何挂起的迁移都将在应用程序启动时执行(使用应用程序凭据)。如果要使用此功能,则需要授予应用程序更改架构的权限。 Flyway 应该在启动 Spring Boot 时运行,因为它是自动配置的。使用 mvn spring-boot:run 从 Maven 启动 Spring Boot 应用程序。 Spring Boot 具有更多用于 Flyway 配置的属性:docs.spring.io/spring-boot/docs/current/reference/html/… 当我运行 mvn spring-boot:run 时,flyway 似乎没有运行(不更新数据库),并且当我执行该命令时,输出中没有任何关于 flyway 的记录。 1.确保您已打开 org.flywaydb 包的日志输出。 2. 检查是否正在构造适当的对象(如 DbValidate 构造函数中的断点)。 3. 这可能很明显:@Sebastian 建议通过 maven 命令启动应用程序,但如果在开发期间从 IDE 启动,您可能更喜欢启动。 4. Spring Boot 依赖自动配置来有条件地创建 bean。在我们的例子中,自动配置类如果 FlywayAutoConfiguration,检查所有条件是否都是肯定的(例如:你是否有一个 DataSource bean 等)【参考方案3】:

如果您希望在启动应用时执行 Flyway(使用 spring-boot),只需删除 flyway-maven-plugin 插件,您不需要它。

-- 编辑

顺便说一句,如果你运行maven flyway:migrate,你确实需要在插件上设置凭据(它不访问java资源)。

因此,要么您需要运行此任务 => 您必须在 pom.xml 上的插件中设置凭据。 或者您不需要它,因此您只需删除插件并在 application.yaml 文件中设置凭据以启动应用程序

【讨论】:

不幸的是,这并没有改变任何东西。我将我的 repo 添加到原始帖子中,看看您或其他人是否可以尝试构建它。 好的,我直接看看 我创建了一个分支fix,它可以在没有flyway-maven-plugin 插件的情况下工作您还会看到一些在您的pom.xml 上注释的依赖项,因为我不认识它们,它们似乎需要一些配置才能工作。先试试这个分支,一步一步添加你需要的依赖 无法将fix 分支推送到您的存储库中:/【参考方案4】:

你试过了吗?

application.yml

spring:
    flyway:
        driverClassName: org.postgresql.Driver
        url: "jdbc:postgresql://localhost:5433/myDB"
        user: postgres
        password: test123
        enabled: true

【讨论】:

【参考方案5】:

您的配置有一些遗漏的时刻:

Spring Boot 的.yml 配置文件使用了太多空格。每个下一个级别应包含 2 个以上的空格,例如:
spring:
  datasource:
    url: jdbc:postgresql://localhost/myDB
    username: postgres
    password: root

没有了。否则就不行!

如果您使用 IntelliJ Idea,您可以使用自动格式化快捷方式来格式化 .ymlCtrl + Alt + L

或者您可以使用与.properties 相同的样式:

spring.datasource.url: ...
spring.datasource.username: ...

更多冗余。但是,出错的机会较小。

您正在使用 Spring Boot。因此,您无需直接包含版本。 Spring 的依赖管理会更好:
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
</plugin>

在大多数情况下,您可以确定这样的版本组合可以正常工作。

您应该将您的迁移文件放在resources/db/migration 下。命名也很重要。第一个文件应该是这样的:

V1__Init_Db.sql

默认情况下,V1 后面正好有两个下划线 -> V1__

这里有更多信息:Migrations information。

另外,请检查您是否需要为配置文件添加其他值,例如:
spring.jpa.show-sql: true
spring.jpa.hibernate.ddl-auto: create

【讨论】:

@JackCole 你有没有尝试解决你的问题? 所以我能够解决这个问题。 Flyway 必须运行两次:编译前一次,启动服务器时一次。要在启动服务器之前运行它,您必须在 pom.xml 中定义一个配置。在服务器启动之前运行的是一个使用 application.yml 的 spring-boot 插件。

以上是关于Spring Boot FlywayException:无法连接到数据库。配置url、用户和密码的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring Boot:Spring Boot启动原理分析

Spring Boot:Spring Boot启动原理分析